From debbugs-submit-bounces@debbugs.gnu.org Sat May 04 14:02:22 2019 Received: (at submit) by debbugs.gnu.org; 4 May 2019 18:02:22 +0000 Received: from localhost ([127.0.0.1]:52208 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hMyzN-0006Oz-FR for submit@debbugs.gnu.org; Sat, 04 May 2019 14:02:22 -0400 Received: from eggs.gnu.org ([209.51.188.92]:54408) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hMyzK-0006Of-Pm for submit@debbugs.gnu.org; Sat, 04 May 2019 14:02:19 -0400 Received: from lists.gnu.org ([209.51.188.17]:46550) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hMyzD-00013L-Cd for submit@debbugs.gnu.org; Sat, 04 May 2019 14:02:11 -0400 Received: from eggs.gnu.org ([209.51.188.92]:40500) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hMyzB-0003nP-6E for bug-gnu-emacs@gnu.org; Sat, 04 May 2019 14:02:11 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,FREEMAIL_FROM, URIBL_BLOCKED autolearn=disabled version=3.3.2 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hMyz6-0000tQ-UY for bug-gnu-emacs@gnu.org; Sat, 04 May 2019 14:02:07 -0400 Received: from mail-wr1-x436.google.com ([2a00:1450:4864:20::436]:41990) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hMyz5-0000oS-OV for bug-gnu-emacs@gnu.org; Sat, 04 May 2019 14:02:04 -0400 Received: by mail-wr1-x436.google.com with SMTP id l2so11839673wrb.9 for ; Sat, 04 May 2019 11:01:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version; bh=+lqChYEfJfKf9vZ3WLmGqlr9sjEQHRWBVg+ut8sxvRc=; b=p6N7A2+73QecVYIDJmmc0oY/UHKZK4UYPuuDjPUA7oa3agFie8S1KbcKaSCGZqs1uN skEc/eLzBojJ3jHmHPVJ1q92cg1b21EdI2vO1KxGCVGh1FzM6Qr6AcrHSO6yvHSz1+ax olzuRf/k/dMF7LaaZzdQ90OnjnkeFPgRCQJi7NwUJE8He705zYM4M5+1SLvrMjaIXKuE rG4CuQaN7vaXbCddAaa3OMoBK8Kkc1XKlWOwinStFJvrA8QttBuMdtIen/uvhCjdbbhW zhkxx1EqlI1S+8WyH4XIy1Eiuqt/zWjmk0O8S+oIUoJy3o27lIqJjYta2Yd0+6wlZjxR FAxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version; bh=+lqChYEfJfKf9vZ3WLmGqlr9sjEQHRWBVg+ut8sxvRc=; b=XWuMG2xNDpTyQCZhWrPW5PsJgPnqEEORa9TiiVR2nABIb1yEoYIyY8e2R041RZkg1n clcOZMg2SoKm5JOVW353PjyUKziSwxRPMYozrONV8FsgVT5J6eQ8bY2dc3kUjv+1mP2Q vEtcLlwViRPD3fos0D4trej0YA5m8uQgu0vc3ydibyCiv4UND5vUrYtSm3fC3qyRTY2H MSDe6+M2015WXW+Hnmv4W2ystUi+Zz+dKrOgyCY52g0LQeB4MJ70Int/w4QKsmSVsGYg jHGOqGaYGgpy/k5BxWDrtUfK9aQp3oEWfE7UBVVoBRHyFw0BobUTjaSdklUOvWxqObxG 64yw== X-Gm-Message-State: APjAAAUZYih1u9S7IkBx4mq7jcrqrwEnQ+ETIELcPMIDbx5YHNXv0FRZ 5YW04NXmlwn3N0L4VYgVEGuiSg1F X-Google-Smtp-Source: APXvYqzGfJUSKBoxQtB3SOV8WhLrJY6Mpx4fFeSkKnKZgC+Vw8jmqjYHh8ZOFEtXG5O3gCUgItHVCw== X-Received: by 2002:a5d:6b04:: with SMTP id v4mr10011591wrw.69.1556992914793; Sat, 04 May 2019 11:01:54 -0700 (PDT) Received: from nc10-laptop (2a01cb04010fc800c8771fb97d0446e3.ipv6.abo.wanadoo.fr. [2a01:cb04:10f:c800:c877:1fb9:7d04:46e3]) by smtp.gmail.com with ESMTPSA id z5sm10346175wre.70.2019.05.04.11.01.53 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 04 May 2019 11:01:53 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: bug-gnu-emacs@gnu.org Subject: 27.0.50; [PATCH] Tweak dired-do-shell-command warning about "wildcard" characters Date: Sat, 04 May 2019 20:01:52 +0200 Message-ID: <87zho2cd4f.fsf@gmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::436 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Spam-Score: -1.3 (-) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello, The function dired-do-shell-command checks the user's command for any star or question mark not surrounded by whitespace or backquotes, asking whether they are deliberate, since the character will then be sent as-is to the shell, instead of being replaced with the marked file(s). A silly example: - Open a Dired buffer - M-! echo "Foobar." > foo RET - g - with point on foo: - ! sed 's/\./?/' RET The way the question is phrased bothers me: > Confirm--do you mean to use `?' as a wildcard? The first time I met this prompt was when I included a quoted '?' in my command as in the example above, so I definitely did *not* mean to use '?' as a shell wildcard. Even now, knowing what the question really means, it still trips my brain that I must answer "yes" (as in, "yes, I know Dired will not substitute the marked files") when I mean "no" (as in, "no, I don't mean to use '?' as a wildcard, what is this even ab- oh wait no right I meant yes! Yes! =F0=9F=A4=A6"). I can think of a few ways to solve this: 1. Rephrase the question to be more general, specifically without calling the characters "wildcards"; for example: > Confirm--do you mean to send `?' to the shell without substitution? 2. Parse the command to find out whether the shell will actually use these characters as wildcards. - not sure how portable this would be across different shells - AFAICT the aim of this prompt is simply to warn the user that Dired will not expand these characters; whether the shell will process them as wildcards is irrelevant 3. Add an option to skip this question (more of a workaround than a solution). Favoring option #1, I tried to find alternative questions, but none of the ones I came up with sounded satisfying (most of them included some form of double-negation, which is not the kind of puzzle I want to solve when I'm about to run a hastily-put-together Bash oneliner). I played around with the idea of actually *showing* the "unsubstituted" characters to the user in order to be able to say something like=E2=80=A6 > Confirm--the highlighted characters will not be substituted. > Proceed? =E2=80=A6 and ended up with the attached patch, which I am not entirely satisfied with (for one, it replaces `y-or-n-p' with `yes-or-no-p' merely because the former seems to strip my prompt's text attributes somehow[1]). --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Make-dired-do-shell-command-highlight-unsubstituted-.patch >From f1d6df845909fd8a6fb0500984fd305d6cf6d6fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Sat, 4 May 2019 18:45:43 +0200 Subject: [PATCH] Make dired-do-shell-command highlight unsubstituted characters Stop calling them "wildcards", since they may be quoted, backslash-escaped, etc. NB: y-or-n-p has been changed to yes-or-no-p since the former makes the highlighting disappear, for some reason. * lisp/dired-aux.el (dired--isolated-char-p): (dired--highlight-nosubst-char): New functions. (dired-do-shell-command): Use them. * test/lisp/dired-aux-tests.el: Test new functions. --- lisp/dired-aux.el | 49 +++++++++++++++++++++++++++++++++--- test/lisp/dired-aux-tests.el | 27 ++++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index b81c0d1a4f..2b302e608b 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -79,6 +79,49 @@ dired--star-or-qmark-p (funcall (if keep #'string-match-p #'string-match) x string)) regexps))) +(defun dired--isolated-char-p (command pos) + "Assert whether the character at POS is isolated within COMMAND. +A character is isolated if: +- it is surrounded by whitespace, the start of the command, or + the end of the command, +- it is surrounded by `\\=`' characters." + (let ((n (length command)) + (whitespace '(?\s ?\t))) + (or (= n 1) + (and (= pos 0) + (memq (elt command 1) whitespace)) + (and (= pos (1- n)) + (memq (elt command (1- pos)) whitespace)) + (and + (> pos 0) + (< pos (1- n)) + (let ((prev (elt command (1- pos))) + (next (elt command (1+ pos)))) + (or (and (memq prev whitespace) + (memq next whitespace)) + (and (= prev ?`) + (= next ?`)))))))) + +(defun dired--highlight-nosubst-char (command char) + "Highlight occurences of CHAR that are not isolated in COMMAND. +These occurences will not be substituted; they will be sent as-is +to the shell, which may interpret them as wildcards." + (save-match-data + (let ((highlighted (substring-no-properties command)) + (pos 0)) + (while (string-match (regexp-quote char) command pos) + (let ((start (match-beginning 0)) + (end (match-end 0))) + (unless (dired--isolated-char-p command start) + (add-face-text-property start end 'warning nil highlighted)) + (setq pos end))) + highlighted))) + +(defun dired--no-subst-prompt (command char) + (let ((highlighted-command (dired--highlight-nosubst-char command char)) + (prompt "Confirm--the highlighted characters will not be substituted. Proceed?")) + (format-message "%s\n%s " highlighted-command prompt))) + ;;;###autoload (defun dired-diff (file &optional switches) "Compare file at point with FILE using `diff'. @@ -757,11 +800,9 @@ dired-do-shell-command (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((need-confirm-p command "*") - (y-or-n-p (format-message - "Confirm--do you mean to use `*' as a wildcard? "))) + (yes-or-no-p (dired--no-subst-prompt command "*"))) ((need-confirm-p command "?") - (y-or-n-p (format-message - "Confirm--do you mean to use `?' as a wildcard? "))) + (yes-or-no-p (dired--no-subst-prompt command "?"))) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ccd3192792..77a4232aac 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,6 +114,33 @@ with-dired-bug28834-test (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(ert-deftest dired-test-isolated-char-p () + (should (dired--isolated-char-p "?" 0)) + (should (dired--isolated-char-p "? " 0)) + (should (dired--isolated-char-p " ?" 1)) + (should (dired--isolated-char-p " ? " 1)) + (should (dired--isolated-char-p "foo bar ? baz" 8)) + (should (dired--isolated-char-p "foo -i`?`" 7)) + (should-not (dired--isolated-char-p "foo 'bar?'" 8)) + (should-not (dired--isolated-char-p "foo bar?baz" 7)) + (should-not (dired--isolated-char-p "foo bar?" 7))) + +(ert-deftest dired-test-highlight-metachar () + "Check that non-isolated meta-characters are highlighted" + (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (result (dired--highlight-nosubst-char command "?"))) + (should-not (text-property-not-all 1 14 'face nil result)) + (should (equal 'warning (get-text-property 15 'face result))) + (should-not (text-property-not-all 16 28 'face nil result)) + (should (equal 'warning (get-text-property 29 'face result))) + (should-not (text-property-not-all 30 39 'face nil result))) + (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") + (result (dired--highlight-nosubst-char command "*"))) + (should-not (text-property-not-all 1 10 'face nil result)) + (should (equal 'warning (get-text-property 11 'face result))) + (should-not (text-property-not-all 12 23 'face nil result)) + (should (equal 'warning (get-text-property 24 'face result))) + (should-not (text-property-not-all 25 29 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.20.1 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable WDYT? Assuming that Dired calling unsubstituted characters "wildcards" is indeed a problem, - can someone come up with a better phrasing? - is the highlighting, as implemented in this patch, helpful? - does anybody know why `y-or-n-p' prompts lose their face property? Thank you for your time. K=C3=A9vin [1] Compare: (let ((prompt "foobar ")) (add-face-text-property 3 6 'warning nil prompt) (yes-or-no-p prompt)) With: (let ((prompt "foobar ")) (add-face-text-property 3 6 'warning nil prompt) (y-or-n-p prompt)) In GNU Emacs 27.0.50 (build 2, i686-pc-linux-gnu, GTK+ Version 3.22.11) of 2019-05-02 built on nc10-laptop Repository revision: 17a722982cca4e8e643c7a9102903e820e784cc6 Repository branch: master Windowing system distributor 'The X.Org Foundation', version 11.0.11902000 System Description: BunsenLabs GNU/Linux 9.8 (Helium) Recent messages: Mark saved where search started Mark set Mark saved where search started Mark set Making completion list... Quit [3 times] Mark set Quit [2 times] Type "q" in help window to restore its previous buffer, C-M-v to scroll hel= p. Quit Quit Configured using: 'configure --with-xwidgets' Configured features: XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS GSETTINGS GLIB NOTIFY INOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT LIBOTF XFT ZLIB TOOLKIT_SCROLL_BARS GTK3 X11 XDBE XIM THREADS XWIDGETS JSON PDUMPER LCMS2 GMP Important settings: value of $LANG: en_US.UTF-8 locale-coding-system: utf-8-unix Major mode: Emacs-Lisp Minor modes in effect: global-magit-file-mode: t magit-file-mode: t magit-auto-revert-mode: t auto-revert-mode: t global-git-commit-mode: t async-bytecomp-package-mode: t shell-dirtrack-mode: t show-paren-mode: t minibuffer-depth-indicate-mode: t icomplete-mode: t global-page-break-lines-mode: t page-break-lines-mode: t electric-pair-mode: t diff-hl-flydiff-mode: t global-diff-hl-mode: t diff-hl-mode: t delete-selection-mode: t tooltip-mode: t global-eldoc-mode: t eldoc-mode: t electric-indent-mode: t mouse-wheel-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t column-number-mode: t line-number-mode: t transient-mark-mode: t Load-path shadows: None found. Features: (shadow sort emacsbug sendmail nndoc gnus-dup mm-archive url-cache debbugs-gnu debbugs soap-client url-http url-auth url-gw url url-proxy url-privacy url-expand url-methods url-history url-cookie url-domsuf url-util warnings rng-xsd rng-dt rng-util xsd-regexp xml tabify man mail-extr ffap pulse diff-hl-dired magit-patch flyspell ispell dired-aux dired-x magit-extras hi-lock cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs cus-edit whitespace find-dired xref magit-submodule magit-obsolete magit-blame magit-stash magit-reflog magit-bisect magit-push magit-pull magit-fetch magit-clone magit-remote magit-commit magit-sequence magit-notes magit-worktree magit-tag magit-merge magit-branch magit-reset magit-files magit-refs magit-status magit magit-repos magit-apply magit-wip magit-log which-func imenu magit-diff smerge-mode magit-core magit-autorevert autorevert filenotify magit-margin magit-transient magit-process magit-mode transient git-commit magit-git magit-section log-edit pcvs-util add-log with-editor async-bytecomp async server face-remap eieio-opt speedbar sb-image ezimage dframe magit-utils crm dash shell pcomplete ert pp gnus-async qp gnus-ml nndraft nnmh nnfolder utf-7 epa-file gnutls network-stream nsm gnus-agent gnus-srvr gnus-score score-mode nnvirtual gnus-msg gnus-art mm-uu mml2015 mm-view mml-smime smime dig mailcap nntp gnus-cache gnus-sum gnus-group gnus-undo gnus-start gnus-cloud nnimap nnmail mail-source utf7 netrc nnoo parse-time gnus-spec gnus-int gnus-range message rmc puny dired dired-loaddefs format-spec rfc822 mml mml-sec epa derived epg mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader gnus-win gnus nnheader gnus-util rmail rmail-loaddefs rfc2047 rfc2045 ietf-drums text-property-search time-date mail-utils mm-util mail-prsvr wid-edit markdown-mode rx color noutline outline vc-mtn vc-hg jka-compr cl-print debug backtrace find-func thingatpt help-fns radix-tree executable misearch multi-isearch vc-git vc-bzr vc-src vc-sccs vc-svn vc-cvs vc-rcs project delight advice eighters-theme quail cl-extra help-mode rg rg-ibuffer rg-result wgrep-rg wgrep s rg-history rg-header rg-compat ibuf-ext ibuffer ibuffer-loaddefs grep compile comint ansi-color ring edmacro kmacro disp-table paren mb-depth icomplete page-break-lines elec-pair diff-hl-flydiff diff diff-hl vc-dir ewoc vc vc-dispatcher diff-mode easy-mmode delsel cus-start cus-load mule-util tex-site info package easymenu epg-config url-handlers url-parse auth-source cl-seq eieio eieio-core cl-macs eieio-loaddefs password-cache json subr-x map url-vars seq byte-opt gv bytecomp byte-compile cconv cl-loaddefs cl-lib tooltip eldoc electric uniquify ediff-hook vc-hooks lisp-float-type mwheel term/x-win x-win term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode elisp-mode lisp-mode prog-mode register page menu-bar rfn-eshadow isearch timer select scroll-bar mouse jit-lock font-lock syntax facemenu font-core term/tty-colors frame cl-generic cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese composite charscript charprop case-table epa-hook jka-cmpr-hook help simple abbrev obarray minibuffer cl-preloaded nadvice loaddefs button faces cus-face macroexp files text-properties overlay sha1 md5 base64 format env code-pages mule custom widget hashtable-print-readable backquote threads dbusbind inotify lcms2 dynamic-setting system-font-setting font-render-setting xwidget-internal move-toolbar gtk x-toolkit x multi-tty make-network-process emacs) Memory information: ((conses 8 708714 111581) (symbols 24 31862 1) (strings 16 136515 44484) (string-bytes 1 4039230) (vectors 8 60958) (vector-slots 4 1347636 61628) (floats 8 3359 1168) (intervals 28 69005 689) (buffers 564 56)) --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sun May 05 04:44:31 2019 Received: (at 35564) by debbugs.gnu.org; 5 May 2019 08:44:31 +0000 Received: from localhost ([127.0.0.1]:52951 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hNCl5-0001Ib-60 for submit@debbugs.gnu.org; Sun, 05 May 2019 04:44:31 -0400 Received: from mout.gmx.net ([212.227.15.19]:51381) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hNCl3-0001IK-1U for 35564@debbugs.gnu.org; Sun, 05 May 2019 04:44:29 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1557045862; bh=awhAWkpTDaS3H8cOEFzh8mEyPgTy6TPgLXoYsF6IpVk=; h=X-UI-Sender-Class:Subject:To:References:From:Date:In-Reply-To; b=UegZYBSkFEZTnKpUPr7r2L75ksRIne7w94xJdjf+RpnoDrvNIQvlWK4ubgRBGcOka 37D6Qsfx9zXCx+x77RJgrD8TzpVqdqY0QZQ1G9IEwRepcFiUPrwpqfgE7BvgW8ODDP iwsTk7ZW6davhgFzBBNTxP1QyuFI6gdeHifE8xHk= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from [192.168.1.101] ([212.95.5.233]) by mail.gmx.com (mrgmx005 [212.227.17.190]) with ESMTPSA (Nemesis) id 1MgvrL-1gpHBb1CtZ-00hLMP; Sun, 05 May 2019 10:44:22 +0200 Subject: Re: bug#35564: 27.0.50; [PATCH] Tweak dired-do-shell-command warning about "wildcard" characters To: =?UTF-8?Q?K=c3=a9vin_Le_Gouguec?= , 35564@debbugs.gnu.org References: <87zho2cd4f.fsf@gmail.com> From: martin rudalics Message-ID: <071cc96c-1bf2-f331-8f9e-b3c54a7452da@gmx.at> Date: Sun, 5 May 2019 10:44:21 +0200 MIME-Version: 1.0 In-Reply-To: <87zho2cd4f.fsf@gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: de-DE Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:l+EaNutZpsMrLi9tb4x+5v7Gx2+U97zcuLfAl3y7kcQaK9L1gE5 U644z4Az8fRveHjU5fbklEPAEYsGuoCAQFPDKG70ECarOZSOvyK2rnYSvf7rpelJeBdbNV9 3nk+OsVdXr18ibzVXxVbvTmO66tQWt3p604GMnqvlpDfldzqxc2CVWEC+ZBeBLvA8hEXiev oNwfKyJFui93DnqmFSr4A== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:sUfYCCbdBzM=:dvNuSr5kjZcWCGF0bENKnw nGiP8g8jxK3PIIIdhwiio2OEAZ8K7vVLKt9IIXYHyjqIH2OaUQbSClXukPkR4e50ErklCUYMr 1Iy8rCIeX+EpMKk5wWbFzj+VQnl+Wl7eW2h7kbBON/32N9r7P8rXdf8yRyAJfpkjbb/wz7RAr OeAMvODmAViSJEqmOY8CKXzNa4XFCmaDoLk9hDubI71eR9fIdXEgiQfnpP7xEgNZfqbZWTZsZ rYXHTTZZQXLrULLCxj7QxkzGgdzwGGJA/PE3WUHKeDyyOuYZ9zmdv6ogu1PyzotNaEp0iaehL L4oi8lGqYm0UHjugQvVbcigThImCNB4+IVlJ92JOKLPligiqIfFWeXFPp7XzHWFCXXklAlfDG ps8zHANrG8TV6T6/dJpSWKBh0hji50cAyzd4Qubgv85+x+p0L6zwq/rpIb4MAPmpbv2nMkSA1 jbD0Bvj2gopFo+ooyNgkwLG2u9C60x/048opSqmPEPWdhZKGNhbpfpV1xyQVV1hb2XN5nOPiY 1s9YpsGaQ8DftIhpQGnh4H6pmUbdgPtfyKk/uE6lomwOQaQaNvVXu5I4BSBkOuMY2/vUdFYib 2MKFh0leZMxJp/+fKiZFnwlxXyk61FLnf0pju7EEftsOzzQE6JF6HUl4W3zsxESOFm61NAN3+ CcYeVUQkbShFdy6RJ21ymGfIvTaPtLvLkzIkkl0XqPjJsyg6v39HIMhQ4lZgiYFTOFedQtUtv 2gLMpZGlDm2E9xvT6GOOx3yFYnGAJuAiB8Jamk69C+fh2Knm0AYDm0/lf1mg3xe9RmEKwATgw y0uhnh8sYUaIMJd4KHrmfOqLEAb7UlxylEzXiBZ7u4i5zG+nbDV1NcAu+UFRIJhV1bphgmvUo aPgwspWvjslQdnpCH+cJ7T9IT8FypSE5/jWPCkP5t1UQF+7m0StGVRsbncEQk7kFZXlApNhzg xvwdQy+qNFg== X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 35564 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) > =E2=80=A6 and ended up with the attached patch, which I am not entirel= y > satisfied with (for one, it replaces `y-or-n-p' with `yes-or-no-p' > merely because the former seems to strip my prompt's text attributes > somehow[1]). [...] > [1] Compare: > > (let ((prompt "foobar ")) > (add-face-text-property 3 6 'warning nil prompt) > (yes-or-no-p prompt)) > > With: > > (let ((prompt "foobar ")) > (add-face-text-property 3 6 'warning nil prompt) > (y-or-n-p prompt)) 'y-or-n-p' propertizes the prompt rigidly as (read-key (propertize (if (memq answer scroll-action= s) prompt (concat "Please answer y or = n. " prompt)) 'face 'minibuffer-prompt))))) while 'yes-or-no-p' carefully applies 'minibuffer-prompt-properties' to any text properties provided with PROMPT. martin From debbugs-submit-bounces@debbugs.gnu.org Mon May 06 15:40:16 2019 Received: (at 35564) by debbugs.gnu.org; 6 May 2019 19:40:17 +0000 Received: from localhost ([127.0.0.1]:57484 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hNjTE-0008Gd-J9 for submit@debbugs.gnu.org; Mon, 06 May 2019 15:40:16 -0400 Received: from mail-wr1-f46.google.com ([209.85.221.46]:38624) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hNjT9-0008GG-NZ for 35564@debbugs.gnu.org; Mon, 06 May 2019 15:40:15 -0400 Received: by mail-wr1-f46.google.com with SMTP id k16so18840895wrn.5 for <35564@debbugs.gnu.org>; Mon, 06 May 2019 12:40:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=JjOl4uON+6IYz53ZfrG8kSWPhtNv1ly3WR89yli62UA=; b=UgVUG46sJQRnVIRSUhQQ8YNqmg8zLf7zj9u3rfFfcAIE9N4P3skrro2ya6wW6kvgVQ SiLFVJzMF4bZnmLRx3wMyl/3mWFeC2POnchsgPQynYxBCojhXyFwlQxwkBRwfklEC6O3 wt/7tnsDUH0uoA8FDCKaJ5yfJW+Clii+EV7q4o1ayFWz2FqSJGg0EN4TncrYggngVmek K68tyTzzUComYSsiVcagzSkUJbqFOa85S9QhGpbS3GQuC/tb9MIpTQHNOZgJ/DYEVRUQ 9H3BW2eJ1JQyVmh5gaNKh4DnANLrbMWbHDqG+VwwO1INy1cd6wO5LlIL12HnD4BT6K9u K20Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=JjOl4uON+6IYz53ZfrG8kSWPhtNv1ly3WR89yli62UA=; b=PpRzPeMQc0eDmlsg4JmF0UXlsbyTs79RvYtjSwPVN3+wCk8QrgHDUf/ECr/WqJ85ul 0NO46INk1mtC+6Auj87r6arxLCBqQMM+s6N7MBDj+d5l/nDcxGIep8l4+WhlG8PKB3eK ObigTGpuLyMy/SF+Lu129R2Dhpcqfd1Jul3oRVv+ENXnj7RIQym3x81GBYGILP2ECWk+ 83UoxPytkNu9sAaUoN8z61Y8BheOdhEuxY3vG6V4r97UDpqzOI4+z6uZHjQ0MxuEupgM uvjegzB+Vb/yZCh/KeUo+GA9IrSdQgewmxekATJ+hhMCSLgySBcKpa2A1hetAnYK0i4+ 2Yow== X-Gm-Message-State: APjAAAVPdYiBkOuR23IKaomycqmxoM2FW2sEfG9rorz0T56s6p63zbIT cRwKXn/jsxMlsGksl1CPj0RYgquh X-Google-Smtp-Source: APXvYqw8SWW+0LzWEdnMsJm2gLf++bHOe/n4NkYQ2ZEAbblqML/+zT2FpwvZXsfUGUyqhe8IMuiuxg== X-Received: by 2002:adf:8bc5:: with SMTP id w5mr18933872wra.226.1557171605434; Mon, 06 May 2019 12:40:05 -0700 (PDT) Received: from my-little-tumbleweed (71.142.13.109.rev.sfr.net. [109.13.142.71]) by smtp.gmail.com with ESMTPSA id q7sm12054896wmc.11.2019.05.06.12.40.03 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 06 May 2019 12:40:04 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: martin rudalics Subject: Re: bug#35564: 27.0.50; [PATCH] Tweak dired-do-shell-command warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <071cc96c-1bf2-f331-8f9e-b3c54a7452da@gmx.at> Date: Mon, 06 May 2019 21:40:01 +0200 In-Reply-To: <071cc96c-1bf2-f331-8f9e-b3c54a7452da@gmx.at> (martin rudalics's message of "Sun, 5 May 2019 10:44:21 +0200") Message-ID: <877eb3e5im.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain martin rudalics writes: >> [1] Compare: >> >> (let ((prompt "foobar ")) >> (add-face-text-property 3 6 'warning nil prompt) >> (yes-or-no-p prompt)) >> >> With: >> >> (let ((prompt "foobar ")) >> (add-face-text-property 3 6 'warning nil prompt) >> (y-or-n-p prompt)) > > 'y-or-n-p' propertizes the prompt rigidly as > > (read-key (propertize (if (memq answer scroll-actions) > prompt > (concat "Please answer y or n. " > prompt)) > 'face 'minibuffer-prompt))))) > > while 'yes-or-no-p' carefully applies 'minibuffer-prompt-properties' > to any text properties provided with PROMPT. Well, that's interesting. I dug into yes-or-no-p until I came across `read_minibuf()'; is this the code you are referring to? if (PT > BEG) { Fput_text_property (make_fixnum (BEG), make_fixnum (PT), Qfront_sticky, Qt, Qnil); Fput_text_property (make_fixnum (BEG), make_fixnum (PT), Qrear_nonsticky, Qt, Qnil); Fput_text_property (make_fixnum (BEG), make_fixnum (PT), Qfield, Qt, Qnil); if (CONSP (Vminibuffer_prompt_properties)) { /* We want to apply all properties from `minibuffer-prompt-properties' to the region normally, but if the `face' property is present, add that property to the end of the face properties to avoid overwriting faces. */ Lisp_Object list = Vminibuffer_prompt_properties; while (CONSP (list)) { Lisp_Object key = XCAR (list); list = XCDR (list); if (CONSP (list)) { Lisp_Object val = XCAR (list); list = XCDR (list); if (EQ (key, Qface)) Fadd_face_text_property (make_fixnum (BEG), make_fixnum (PT), val, Qt, Qnil); else Fput_text_property (make_fixnum (BEG), make_fixnum (PT), key, val, Qnil); } } } } If one were to fix the issue of y-or-n-p hardcoding the face property, what would be the best way to go? 1. Make a C DEFUN out of this snippet, and have it called by `read_minibuf()' and `y-or-n-p'. 2. Re-implement this snippet as an Elisp defun, and have it called by `read_minibuf()' and `y-or-n-p'. 3. (Re-implement this snippet within `y-or-n-p'.) (FWIW, the attached patch seems to work as a workaround, but I assume solutions 1 or 2 would be better, by virtue of reusing code) --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Make-y-or-no-p-keep-the-supplied-prompt-s-face.patch >From 9ea712779d725a23fe8f4acd7b934b0a64a1f1ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Mon, 6 May 2019 21:26:37 +0200 Subject: [PATCH] Make y-or-no-p keep the supplied prompt's face * lisp/subr.el (y-or-n-p): append the minibuffer-prompt face instead of overwriting the prompt's face property. --- lisp/subr.el | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lisp/subr.el b/lisp/subr.el index f68f9dd419..8d224ff5bb 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2647,11 +2647,15 @@ y-or-n-p (let ((cursor-in-echo-area t)) (when minibuffer-auto-raise (raise-frame (window-frame (minibuffer-window)))) - (read-key (propertize (if (memq answer scroll-actions) - prompt - (concat "Please answer y or n. " - prompt)) - 'face 'minibuffer-prompt))))) + (read-key + (let ((prompt-maybe-please + (if (memq answer scroll-actions) + prompt + (concat "Please answer y or n. " prompt)))) + (add-face-text-property + 0 (1- (length prompt-maybe-please)) + 'minibuffer-prompt t prompt-maybe-please) + prompt-maybe-please))))) (setq answer (lookup-key query-replace-map (vector key) t)) (cond ((memq answer '(skip act)) nil) -- 2.21.0 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Thanks for your help! K=C3=A9vin --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Tue May 07 04:15:48 2019 Received: (at 35564) by debbugs.gnu.org; 7 May 2019 08:15:48 +0000 Received: from localhost ([127.0.0.1]:58163 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hNvGN-0001RQ-TB for submit@debbugs.gnu.org; Tue, 07 May 2019 04:15:48 -0400 Received: from mout.gmx.net ([212.227.17.21]:59211) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hNvGM-0001RC-AK for 35564@debbugs.gnu.org; Tue, 07 May 2019 04:15:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1557216940; bh=M+Ew0w+/jLPccHQv9GmiVTcO2wRWmoPZZ0BdchD2rho=; h=X-UI-Sender-Class:Subject:To:Cc:References:From:Date:In-Reply-To; b=ThW6D5AZDehdNlPxv7XQ+9CzOF2J/QZUln2Yh5sDuL8xDHApPV4nmHERyAEmn40pn OiZ4FqS+Fg5lc9DivDvQnECjAKY9hozX1qRZUJJUilUeZZ+H2nFfB7BKUgMXc3DHcS PVrDKXxbWA6y3pGw9T79sHXPiTjetHM70lQV3Aug= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from [192.168.1.101] ([212.95.5.94]) by mail.gmx.com (mrgmx101 [212.227.17.168]) with ESMTPSA (Nemesis) id 0MJGFi-1hQf573g66-002lN9; Tue, 07 May 2019 10:15:39 +0200 Subject: Re: bug#35564: 27.0.50; [PATCH] Tweak dired-do-shell-command warning about "wildcard" characters To: =?UTF-8?Q?K=c3=a9vin_Le_Gouguec?= References: <87zho2cd4f.fsf@gmail.com> <071cc96c-1bf2-f331-8f9e-b3c54a7452da@gmx.at> <877eb3e5im.fsf@gmail.com> From: martin rudalics Message-ID: <9bd289fe-3623-4c45-4c4f-04c6668cae76@gmx.at> Date: Tue, 7 May 2019 10:15:42 +0200 MIME-Version: 1.0 In-Reply-To: <877eb3e5im.fsf@gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: de-DE Content-Transfer-Encoding: 7bit X-Provags-ID: V03:K1:UunCkSMnvbAPI9igSPMOeA3O7xsJ58px7hjZYtkBTjQX+ISnDLL jwF6UQz2s74rCg0bkqtAsvmbYfPYiOCRR7D1Ve/jFppJS+s5uXJy65CQTLAEuYXSFt77XkU X/6/SO2tPpC2O4FclSYkyAUmEsBHAQPZmMsUWOOeWJGISH2AVoi7tcXUu3caWkqZ7Uq+edp 1P/KpSwvcKI3PTJdnm8mw== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:LkDQuh2HP9I=:nUO4oWXRzPjLE13rt8qkSd 0qK9wCix9WmvjoHrvfDG2/dH/BHu6WtygJlJkPLmjNTAtPRjhAzMMGdMZSgN+5NIjOZnGhIDG Rm24dV1RVJW2Tt5ancdHuZqYMttDHxE4kjqx8ADF/bkwTVJ3BFnMFaeS7E4YpcRwYc9N6PS6C S0+HesCumn8n3A7qgoy1VaC3xiEfcsc91fQHsBY/gDLlrBAusoJsYq5yCceDk3OsMfhIh7I04 M3w8O5RxFDAQpf5eDy8JwhJ1xnswH5YWNFAw1rLX5jsyOYoOl2ExHEpARsJ4uDPKrEmJuWT24 PGHPYS3wF5OSlOWMlFKdlC5GWi/O3nZOuKoPjwJktrWnMkJurdXW8nCoQae9Sx6xHy9TreWZZ M6AHJAsBnEQqDxoC7Jnw57o95PDl4tZSgk2OdOUBX3APSz2nQpi6qDMwYDFQqcWOZD7vA0SJk BJpn09wdj0V5ogq11GzfiRf7VdDpt5UF+Fif8A4e0HWt4Lk3GeRHIXBALHIEh2st58nt2wmhj CYMCmwz0Dzj8cFts5+so8cK2NKRDcontSHyfyRzQCJA+VrsdKMza9PxKNCNKe9koH9JGvp/eJ hJGEWDgdDqgaJziL7zYwJtaW7evUmQrb21rUJQJech1VMVPj3nImgPR1p4A71WPh1VORlBEr6 lCTDRfR+jA4+IH7PixyvCWIIbW84P5QdDKIyeeapiMT+3nbr3CIZvn3cBrJ5wCcMEvNaj9ZGf 7t4xz8h37INoVFdlti6opP3c0SH3qiP44YZR2x8dwNja7VvByznqGZ6/Chj9Dkh85h0J3i9lO 2Fh8+mLbk9P0LlQbssUZ9HC93irskvx0LNNjI9vEtrVVd+8fBg2dcyeLkeZ43bXYjQmbJ12XO 672oM1qr4rHrOatUMSm3nypyGV8PUO6tKuKZiwUUW5MFrbeJyVR7oHamuv/EF006vn3GPIAkQ h5eElFFF4hQ== X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) > I dug into yes-or-no-p until I came across `read_minibuf()'; is this the > code you are referring to? It is. > If one were to fix the issue of y-or-n-p hardcoding the face property, > what would be the best way to go? > > 1. Make a C DEFUN out of this snippet, and have it called by > `read_minibuf()' and `y-or-n-p'. > > 2. Re-implement this snippet as an Elisp defun, and have it called by > `read_minibuf()' and `y-or-n-p'. > > 3. (Re-implement this snippet within `y-or-n-p'.) > > (FWIW, the attached patch seems to work as a workaround, but I assume > solutions 1 or 2 would be better, by virtue of reusing code) By design, 'yes-or-no-p' and 'y-or-n-p' are kept apart to avoid that people use the latter for more "crucial decisions". Part of this distinction is that 'y-or-n-p' is asked in the echo area, so applying 'minibuffer-prompt-properties' would be conceptually inappropriate. Obviously, applying 'minibuffer-prompt' is just as inappropriate (that face is part of 'minibuffer-prompt-properties') but that's a decision that has been made long ago. So although I'd vote for a solution like the one you propose in your patch, any decision in this area is subtle and should be approved by others first. Also because we'd then have to decide what to do with other clients of the 'minibuffer-prompt' face like 'read-char-choice' or the ones in isearch.el. martin From debbugs-submit-bounces@debbugs.gnu.org Tue May 07 09:19:23 2019 Received: (at 35564) by debbugs.gnu.org; 7 May 2019 13:19:23 +0000 Received: from localhost ([127.0.0.1]:58379 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hO00B-0007Le-Ae for submit@debbugs.gnu.org; Tue, 07 May 2019 09:19:23 -0400 Received: from userp2120.oracle.com ([156.151.31.85]:47498) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hO009-0007LM-A9 for 35564@debbugs.gnu.org; Tue, 07 May 2019 09:19:22 -0400 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x47DIaEC179278; Tue, 7 May 2019 13:19:14 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=Gro0WsLvTKu4OJw7A8+qDJcX4tgNx4/ejIL0J6LaBHg=; b=upUA/neVvz7M9Gg2OYHfjI38XCnUM0T0A7VUMADbw9N8RyN6wYVUACbOZyKdbOSyjbo/ nmMEAnt5LRmYTgr6rdS0D0uCh2Iz9Z//BI5D0caN1nPzi094c2FYUVHjdqtliZ7E5lts 3HE0ZCitImuDdi6CyC0qmZxF25J0EUGVrGG4ht51CENERHPbLPfMHGtqiY1FBGgc/IlE dts37SosQZdCAQbw7N4uS/2HGgucARoizdxu7dXx/Pp7LeNiRNYP9qCUYW1+nN/euPb+ FBk5wEN/IWaoDZbKPHU9FpGfZeIVxL2To05qBTeWAZHtjRhhr18AO08P3FrdiCLyQ7pl UQ== Received: from aserp3030.oracle.com (aserp3030.oracle.com [141.146.126.71]) by userp2120.oracle.com with ESMTP id 2s94b0n6eu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 07 May 2019 13:19:13 +0000 Received: from pps.filterd (aserp3030.oracle.com [127.0.0.1]) by aserp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x47DIxVx137943; Tue, 7 May 2019 13:19:13 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserp3030.oracle.com with ESMTP id 2s94b9fe0v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 07 May 2019 13:19:13 +0000 Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x47DJBvl031148; Tue, 7 May 2019 13:19:11 GMT MIME-Version: 1.0 Message-ID: <9fc1129c-5377-4b56-ba6d-dce497140941@default> Date: Tue, 7 May 2019 06:19:10 -0700 (PDT) From: Drew Adams To: martin rudalics , =?utf-8?B?S8OpdmluIExlIEdvdWd1ZWM=?= Subject: RE: bug#35564: 27.0.50; [PATCH] Tweak dired-do-shell-command warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <071cc96c-1bf2-f331-8f9e-b3c54a7452da@gmx.at> <877eb3e5im.fsf@gmail.com> <9bd289fe-3623-4c45-4c4f-04c6668cae76@gmx.at> In-Reply-To: <9bd289fe-3623-4c45-4c4f-04c6668cae76@gmx.at> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4834.0 (x86)] Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9249 signatures=668686 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1905070087 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9249 signatures=668686 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1905070087 X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > By design, 'yes-or-no-p' and 'y-or-n-p' are kept apart to avoid that > people use the latter for more "crucial decisions". Part of this > distinction is that 'y-or-n-p' is asked in the echo area, so applying > 'minibuffer-prompt-properties' would be conceptually inappropriate. > Obviously, applying 'minibuffer-prompt' is just as inappropriate (that > face is part of 'minibuffer-prompt-properties') but that's a decision > that has been made long ago. >=20 > So although I'd vote for a solution like the one you propose in your > patch, any decision in this area is subtle and should be approved by > others first. Also because we'd then have to decide what to do with > other clients of the 'minibuffer-prompt' face like 'read-char-choice' > or the ones in isearch.el. I don't see any good reason why face `minibuffer-prompt' should be used, especially by default (users can do whatever they like) for situations where there is no active minibuffer, i.e., for prompting situations generally. It should instead serve as a useful clue that the minibuffer is being used. (Just one opinion.) From debbugs-submit-bounces@debbugs.gnu.org Wed May 08 16:42:56 2019 Received: (at 35564) by debbugs.gnu.org; 8 May 2019 20:42:56 +0000 Received: from localhost ([127.0.0.1]:34162 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hOTOx-0005vL-OS for submit@debbugs.gnu.org; Wed, 08 May 2019 16:42:56 -0400 Received: from mail-wm1-f67.google.com ([209.85.128.67]:35647) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hOTOw-0005v2-3d for 35564@debbugs.gnu.org; Wed, 08 May 2019 16:42:54 -0400 Received: by mail-wm1-f67.google.com with SMTP id y197so296313wmd.0 for <35564@debbugs.gnu.org>; Wed, 08 May 2019 13:42:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=9ijUDtjRfu2Yz9a0aK2g3lpaL/qyd6gwMqzMGGOE0L4=; b=qevMt2yx8Pj+MZbp6Zh5d173LXkC0j2PoK1pFTgD/PsJptoELmAPjWL4CQVPoLHPin DUHMnmQ36JAuym9n4I9WXtvpqaX3cV/ztDQLA3rFNUb2R6xWhqA/XMPkZNymU0d4lOUt 0n87ek75Xl6gSzNRF3AFCGIyxcN85NY/KNbyqF1YloRnq+FkuwSGUhwlmVRWHwmVMAXR MsOSEEdDmNeG2p0ZBvPUr5ZtYbQR7YaM5wdHPDxdIIdUqQfMdNVVViqNEoHT5gZRJPG1 oMXdVY5X6sgatuN9AWeCxl1GtIPhGFYD4sV+gdn0jEnchwGMp4X1I993bb0P4JrC03bm d+wQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=9ijUDtjRfu2Yz9a0aK2g3lpaL/qyd6gwMqzMGGOE0L4=; b=ndGjCPO041Zq/FwpjPkEqA7RO2CsS5XJJXUtSAFtAagksYgDujusW7gU1YsNyUNvlj b0DN6DTfdAlpAMTeHQHROT+9r+br/eFljKoRGah+1sru3DJTBSA2wYJrMLzcST5Od3vQ 2ne2bwsQksqz/l7+C5rwZvOeMa5C9PW9ScX049OvHkFIpe7o5kCylMVe9bnzhz9xVqK8 fu7yLKgGWLolpNBRLGbDEgUTcC4OfrLk3vmHkrzm+aT386MGLn6NhNwF75IEhszmV/jS zlLOyx60nlcTAA8uJ7diO6isVeOKq92q3w2BiQZkdOYVMLVUu1ddmQW3qUefHgINFvM5 WHfQ== X-Gm-Message-State: APjAAAXjSwWCwE8ZVmCIdUIsEkiw1bMQKjmZr0gauRc527QfAI09eem3 fFAM24enEitEImquLRWqkE9qVdhT X-Google-Smtp-Source: APXvYqyue9f+FSjCqB+0NE75t2G97CraoY00smwApaOCk9MIa0F3gYec1uCQ/fmMu7SAB6+/DKkTxA== X-Received: by 2002:a7b:ce06:: with SMTP id m6mr146613wmc.62.1557348167981; Wed, 08 May 2019 13:42:47 -0700 (PDT) Received: from my-little-tumbleweed (71.142.13.109.rev.sfr.net. [109.13.142.71]) by smtp.gmail.com with ESMTPSA id s3sm35692567wre.97.2019.05.08.13.42.46 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 08 May 2019 13:42:46 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Drew Adams , martin rudalics Subject: Re: bug#35564: 27.0.50; [PATCH] Tweak dired-do-shell-command warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <071cc96c-1bf2-f331-8f9e-b3c54a7452da@gmx.at> <877eb3e5im.fsf@gmail.com> <9bd289fe-3623-4c45-4c4f-04c6668cae76@gmx.at> <9fc1129c-5377-4b56-ba6d-dce497140941@default> Date: Wed, 08 May 2019 22:42:45 +0200 In-Reply-To: <9fc1129c-5377-4b56-ba6d-dce497140941@default> (Drew Adams's message of "Tue, 7 May 2019 06:19:10 -0700 (PDT)") Message-ID: <877eb0ptiy.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Drew Adams writes: > I don't see any good reason why face `minibuffer-prompt' > should be used, especially by default (users can do > whatever they like) for situations where there is no > active minibuffer, i.e., for prompting situations > generally. It should instead serve as a useful clue > that the minibuffer is being used. (Just one opinion.) I'd hazard a guess[1] that this was done to make y-or-n-p and yes-or-no-p similar from a UI point of view: they both prompt the user for a binary answer, therefore the prompt might as well look the same in both situations. >From what I can tell the use of 'minibuffer-prompt' in minibuffer-less situations has enough precedents (the "other clients" Martin mentions) that the "minibuffer-" prefix might be considered a historical accident by now=E2=80=A6 (Perhaps those clients could be migrated to a new face, e.g. 'message-prompt', which would inherit 'minibuffer-prompt' by default?) martin rudalics writes: > So although I'd vote for a solution like the one you propose in your > patch, any decision in this area is subtle and should be approved by > others first. Also because we'd then have to decide what to do with > other clients of the 'minibuffer-prompt' face like 'read-char-choice' > or the ones in isearch.el. Fair enough. Should I raise the issue on emacs-devel, or create a new bug report? Just to make sure I am not omitting something, is this how you would sum up the issue? - In the context of bug#35564, I would like to add text properties to the y-or-n-p prompt (although I'm open to other, simpler solutions e.g. simply changing Dired's message). - While this can be patched within y-or-n-p and we can call it a day, the minibuffer-prompt-face-adding code could be factored out of 'read_minibuf'. - This raises two questions: 1. Do we actually want to use the 'minibuffer-prompt' face in this context, since the minibuffer is not involved? =20=20=20=20=20=20=20 2. What do we do with other clients of 'minibuffer-prompt', which use the same (propertize prompt 'face 'minibuffer-prompt) idiom? Thank you both for your thoughts on this. [1] AFAICT, the commit that added this face (927be33, back when y-or-n-p was still a C function) does not say why this was thought to be a good idea. From debbugs-submit-bounces@debbugs.gnu.org Wed May 08 18:40:07 2019 Received: (at 35564) by debbugs.gnu.org; 8 May 2019 22:40:07 +0000 Received: from localhost ([127.0.0.1]:34244 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hOVEN-0002SB-1V for submit@debbugs.gnu.org; Wed, 08 May 2019 18:40:07 -0400 Received: from aserp2130.oracle.com ([141.146.126.79]:44018) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hOVEL-0002Rd-Q7 for 35564@debbugs.gnu.org; Wed, 08 May 2019 18:40:06 -0400 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x48Mdgd8058753; Wed, 8 May 2019 22:40:00 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=M+BonKoczVdH8maEvqLDCQbii9+PdXZzjAfujKHEMdw=; b=b5Kjvk7XxIdjXFXlQAadCkkyi6byzaydu533JDUsauTguU8uA+R9eZfMUQpeIC2Mbs4x xKjggR1ddIoExz2UyUY5cOtoHcuNk27SJcmvZ2eg1qN2jThzjnPlmhUcBr3dLKBVkQT1 kDBEKzGrbLr7SuM4MW7JnSgTVfjj+d4jA/hAT6DPa+XZK45ngpkMe4kIlpgxkOMuNQNI UOtJul7tN96KgWujiCYYGgXImW4vvuAVHapGxyBCgbej7UTk45D2iCUWbbpxn1aMllfv H6Eqc4pBQGc6zxPqC/oUzmEIV05gtVTPUgkGxSkQOgukLOEwLU+Mk8+UGQJkS0X6KbmR 3w== Received: from userp3030.oracle.com (userp3030.oracle.com [156.151.31.80]) by aserp2130.oracle.com with ESMTP id 2s94b67av8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 08 May 2019 22:39:59 +0000 Received: from pps.filterd (userp3030.oracle.com [127.0.0.1]) by userp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x48Mdw3a092858; Wed, 8 May 2019 22:39:59 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userp3030.oracle.com with ESMTP id 2sagyuw67d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 08 May 2019 22:39:59 +0000 Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x48MdvwI029603; Wed, 8 May 2019 22:39:57 GMT MIME-Version: 1.0 Message-ID: Date: Wed, 8 May 2019 15:39:56 -0700 (PDT) From: Drew Adams To: =?utf-8?B?S8OpdmluIExlIEdvdWd1ZWM=?= , martin rudalics Subject: RE: bug#35564: 27.0.50; [PATCH] Tweak dired-do-shell-command warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <071cc96c-1bf2-f331-8f9e-b3c54a7452da@gmx.at> <877eb3e5im.fsf@gmail.com> <9bd289fe-3623-4c45-4c4f-04c6668cae76@gmx.at> <9fc1129c-5377-4b56-ba6d-dce497140941@default> <877eb0ptiy.fsf@gmail.com> In-Reply-To: <877eb0ptiy.fsf@gmail.com> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4834.0 (x86)] Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9251 signatures=668686 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1905080134 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9251 signatures=668686 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1905080135 X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > Drew Adams writes: >=20 > > I don't see any good reason why face `minibuffer-prompt' > > should be used, especially by default (users can do > > whatever they like) for situations where there is no > > active minibuffer, i.e., for prompting situations > > generally. It should instead serve as a useful clue > > that the minibuffer is being used. (Just one opinion.) >=20 > I'd hazard a guess[1] that this was done to make y-or-n-p and > yes-or-no-p similar from a UI point of view: they both prompt the user > for a binary answer, therefore the prompt might as well look the same in > both situations. >=20 > From what I can tell the use of 'minibuffer-prompt' in minibuffer-less > situations has enough precedents (the "other clients" Martin mentions) > that the "minibuffer-" prefix might be considered a historical accident > by now=E2=80=A6 Not an accident. The "precedents" are themselves bugs, IMO. The minibuffer is the minibuffer. It's important that users be aware when it is active. That may not matter much for `yes-or-no-p', as it insists on "yes" or "no". But it is important for the minibuffer in general. The minibuffer is an editing buffer; you can do lots of things in it and with it. > (Perhaps those clients could be migrated to a new face, > e.g. 'message-prompt', which would inherit 'minibuffer-prompt' by > default?) That would be fine by me. Or no face. Is it really important that the prompt be distinguished by a face? (To be clear, I have no objection to our using faces for prompts.) > - In the context of bug#35564, I would like to add text properties to > the y-or-n-p prompt (although I'm open to other, simpler solutions > e.g. simply changing Dired's message). I wouldn't mention bug #35564. And that bug should not, itself, also deal with prompt faces. It should be only about `dired-do-shell-command' warning about wildcard characters. Any question (for this command or in general) about prompt faces is independent of this bug report about the `dired-do-shell-command' treatment of wildcards. (Just one opinion.) From debbugs-submit-bounces@debbugs.gnu.org Thu May 09 04:13:16 2019 Received: (at 35564) by debbugs.gnu.org; 9 May 2019 08:13:16 +0000 Received: from localhost ([127.0.0.1]:34615 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hOeB2-0001Bd-JW for submit@debbugs.gnu.org; Thu, 09 May 2019 04:13:16 -0400 Received: from mout.gmx.net ([212.227.15.18]:33521) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hOeB0-0001BQ-9F for 35564@debbugs.gnu.org; Thu, 09 May 2019 04:13:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1557389583; bh=+XoNa+viqVNcEV0jW9P+P/PzfjLxvHu7RT2wfawZ400=; h=X-UI-Sender-Class:Subject:To:Cc:References:From:Date:In-Reply-To; b=kO+Jek/ZrJlMP1noHZ9CYJ7exanyX5gwuTuMiWt5bE67pnC3YBBcd8kDWU+ec1fhr dyi3PNICiDljB3OGAYrQvxN2YMmWVuaEXb1S4++kvJgc7+cALtsRQ0eOfbpLzfiUZ7 VIDJaOmU4IMavCSXWHFetRrUtPqdZPgNsyznOJrk= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from [192.168.1.101] ([212.95.5.238]) by mail.gmx.com (mrgmx002 [212.227.17.190]) with ESMTPSA (Nemesis) id 0MTTKZ-1hG1cW1hJf-00SMcQ; Thu, 09 May 2019 10:13:03 +0200 Subject: Re: bug#35564: 27.0.50; [PATCH] Tweak dired-do-shell-command warning about "wildcard" characters To: =?UTF-8?Q?K=c3=a9vin_Le_Gouguec?= , Drew Adams References: <87zho2cd4f.fsf@gmail.com> <071cc96c-1bf2-f331-8f9e-b3c54a7452da@gmx.at> <877eb3e5im.fsf@gmail.com> <9bd289fe-3623-4c45-4c4f-04c6668cae76@gmx.at> <9fc1129c-5377-4b56-ba6d-dce497140941@default> <877eb0ptiy.fsf@gmail.com> From: martin rudalics Message-ID: Date: Thu, 9 May 2019 10:13:06 +0200 MIME-Version: 1.0 In-Reply-To: <877eb0ptiy.fsf@gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: de-DE Content-Transfer-Encoding: 7bit X-Provags-ID: V03:K1:wHIfpgAhk8T10624QlPQ0nhf6/UkMzCOaEtGAUTRDJCuozUEjdk 6PajqNKieaGekE8aLGEqY4xPD1TwUYXZx1+A6jbwOrztcv3/pxAEsu2h9owcsYY3Xv1F4ZM 8siWoE3ZATgRv0ib9KhxYzK9fUxYoATY79vVMOmQ1klqrQz+c7u4vHb2Mw9eKJLCvLF04zX lVTLO2spnvarw6htRItUg== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:vyKLGKePqYI=:wANLkcwLjjRBBLHM7f3Jn8 nwLwlkclc5wKXs0tyGtIypsnlCeE/S9HsZOhCGu6B2Q9kCflK5tZPQEo4eJeJLnTkFs/eGWDt c2CNuUiqe3q2NjvU1rcY8eXr12EQR6Ohw0wY7mBIIqcgJJyWXKMYpiVseBru1jN/4q11Q9Vkz FhqWk1rWYG8+4PAyTeHgkJGwYz2VKwMO4LbWnCixAN5tixVu6gL4IB1rzuLFrw3/hngVpSLb2 BqMzCViM2Mdfm2qmBgxRQf16emYY8mTtzSPZLbvwbFIzfjwmu+WAqYgAglHkNHjQFsudW1yIl lROhOPf3XuPN0uG5LBUXixVXI0hepP+ULR3HvZzFn03bdF+biESaTceIgdD+gBPNbpYloItIG 4etzsdxWM4ALXFqy8cVLE8pYGWoRwjt0IG2lnOSV+VBh+5pCuZTAPCOATwf6r41cR8vMjw5Xt SGSfTiFOXPMmdYK1qQ90/IT0MIx+FsoyXzJweJPN2y8iBBczkkzKIqy7edDPukvjsmjVXqlyM 4favdlvdv9LOr9AVo9YbHiypG9VfRFAJTfXpVgDWzlfrcuvoMZG17rJGBKEjKZ9KHVS8gLzTN EXd3+3y5auBFVo18Fs5jVrTR3IPjU747eik+/I3z4IgYHj+Clwcah/XEd/pNTZ+u5/km1ROXW WLZKssE9fawoyaLU+Pn/2NaH5qwEk1UlGHe9worn26A0OGZbQZHYRLp1o7o3QmIZUbz3+1oxu 7RxaOsm4R1byDaRF4+kz4Zb2ZPXlCZKVN6ei6nHpdG9ET5hsh3ROzqnObxc0G3tfE6ZcbNHGd L1yvtWxpa+YX2PZ3btbyal+JM2ZL6iWhbneEilN5GRFoisTpC5WhIwlYGJFtoGCEgWh7FxuVV lUA38mx6Nilb/5z8CBeAdsXZxdJYDL4AUJpXsmY/DAQURKH5xMsDTn6UyV+fcE8l7MU1Zmdfz AWG06iuDgqg== X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) > (Perhaps those clients could be migrated to a new face, > e.g. 'message-prompt', which would inherit 'minibuffer-prompt' by > default?) Simply 'prompt' would be more intuitive since most messages do not show prompts. But I'm afraid we'll have to stick to what we have now. > Fair enough. Should I raise the issue on emacs-devel, or create a new > bug report? Just to make sure I am not omitting something, is this how > you would sum up the issue? > > - In the context of bug#35564, I would like to add text properties to > the y-or-n-p prompt (although I'm open to other, simpler solutions > e.g. simply changing Dired's message). > > - While this can be patched within y-or-n-p and we can call it a day, > the minibuffer-prompt-face-adding code could be factored out of > 'read_minibuf'. > > - This raises two questions: > > 1. Do we actually want to use the 'minibuffer-prompt' face in this > context, since the minibuffer is not involved? > > 2. What do we do with other clients of 'minibuffer-prompt', which > use the same (propertize prompt 'face 'minibuffer-prompt) idiom? That would sum it up (but since I don't use Dired I can't comment on that). Note that this isssue also touches one Drew raised elsewhere - whether 'tooltip-show' should retain face properties of the original text or show text uniformly with the 'tooltip' face. Maybe we should introduce an option like 'prompts-retain-text-properites' so users have the choice. > [1] AFAICT, the commit that added this face (927be33, back when y-or-n-p > was still a C function) does not say why this was thought to be a > good idea. It's probably part of a concept to have prompts appear uniformly and integrate them into the framework of themes. Note that Emacs usually cannot control the appearance of dialog boxes or system tooltips. martin From debbugs-submit-bounces@debbugs.gnu.org Thu May 09 10:20:07 2019 Received: (at 35564) by debbugs.gnu.org; 9 May 2019 14:20:07 +0000 Received: from localhost ([127.0.0.1]:36015 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hOju2-0003xm-T8 for submit@debbugs.gnu.org; Thu, 09 May 2019 10:20:07 -0400 Received: from userp2130.oracle.com ([156.151.31.86]:42306) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hOju0-0003xD-CK for 35564@debbugs.gnu.org; Thu, 09 May 2019 10:20:05 -0400 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x49DwspX157416; Thu, 9 May 2019 14:19:58 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=2aRX+hBrV1wwj6HpOAHsb65kqC8Vy9ojq6HsM7CPBZM=; b=QxVSrPzrV2l4Cl/ODSXEGa9RdC1BBR8L4ClgTClEUwC72xjs5slQIjOwEcb2ppVeclEh KNhOtNrFCDDmtmR/u6RuZeCm8xYPsILluCXpSsHt0RniT6MHKu6348c3dl9wBGQbAqsx mI4k2RpiBCSHOpnRKixhwiqbINH/Umzw+d7hPN8rf540rC8TOrsHMTQUvPou//8zED3X xiQwWQXxJ76Fc2G5U2njHQMjd55xMDai5LtT1m7hLNIGfo10i7ALbMG/5dSZSqWTptNN okbzwNQI4z00CSfcChvQDRhzXxIen6i4LTUL7AiDSbnCMG+hQOlQ3xPzJKjlMgfZBeGm fQ== Received: from userp3030.oracle.com (userp3030.oracle.com [156.151.31.80]) by userp2130.oracle.com with ESMTP id 2s94bgb619-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 09 May 2019 14:19:58 +0000 Received: from pps.filterd (userp3030.oracle.com [127.0.0.1]) by userp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x49EHwPK170957; Thu, 9 May 2019 14:17:58 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userp3030.oracle.com with ESMTP id 2sagyv91re-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 09 May 2019 14:17:58 +0000 Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x49EHr7Q026948; Thu, 9 May 2019 14:17:54 GMT MIME-Version: 1.0 Message-ID: Date: Thu, 9 May 2019 07:17:53 -0700 (PDT) From: Drew Adams To: martin rudalics , =?utf-8?B?S8OpdmluIExlIEdvdWd1ZWM=?= Subject: RE: bug#35564: 27.0.50; [PATCH] Tweak dired-do-shell-command warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <071cc96c-1bf2-f331-8f9e-b3c54a7452da@gmx.at> <877eb3e5im.fsf@gmail.com> <9bd289fe-3623-4c45-4c4f-04c6668cae76@gmx.at> <9fc1129c-5377-4b56-ba6d-dce497140941@default> <877eb0ptiy.fsf@gmail.com> In-Reply-To: X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4834.0 (x86)] Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9251 signatures=668686 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1905090084 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9251 signatures=668686 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1905090084 X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > > (Perhaps those clients could be migrated to a new face, > > e.g. 'message-prompt', which would inherit 'minibuffer-prompt' by > > default?) >=20 > Simply 'prompt' would be more intuitive since most messages do not show > prompts. Sounds OK to me. > But I'm afraid we'll have to stick to what we have now. Why? Not sure what you mean. > Note that this isssue also touches one Drew raised elsewhere - whether > 'tooltip-show' should retain face properties of the original text or > show text uniformly with the 'tooltip' face. Maybe we should > introduce an option like 'prompts-retain-text-properites' so users > have the choice. I would prefer that the two be separated. Tooltip text is quite different from prompts in use cases and behavior. Wrt tooltips, I also don't see why we need an option, or even a defvar. Tooltips should just accept and respect propertized strings. When you use `x-show-tip' there is no such problem - you can apply properties as usual. It is only `help-echo' tooltips that do not respect properties (AFAIK). Another, simpler possibility, for dealing with face `tooltip': It is not possible to simply _bind_ a face for the duration (or lex scope) of a function. But if we use a face variable for this, e.g. `tooltip-face', then it should be simple to do so. IOW, work around the limitation that you cannot bind a face by binding a face variable and using that for `help-echo'. That should make it simple for any code to control the appearance of the tooltip text. From debbugs-submit-bounces@debbugs.gnu.org Thu May 09 13:51:39 2019 Received: (at 35564) by debbugs.gnu.org; 9 May 2019 17:51:39 +0000 Received: from localhost ([127.0.0.1]:36326 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hOnCl-0000lm-F7 for submit@debbugs.gnu.org; Thu, 09 May 2019 13:51:39 -0400 Received: from mout.gmx.net ([212.227.17.22]:59353) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hOnCj-0000lW-9L for 35564@debbugs.gnu.org; Thu, 09 May 2019 13:51:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1557424285; bh=lYckT3R96aEQXwwZZuoCSk5P7gBkn/Lpt6bNeYpaWfU=; h=X-UI-Sender-Class:Subject:To:Cc:References:From:Date:In-Reply-To; b=BmglLR1LxkzlM8zcqD4QInZEGz9kFlsIBCiOL7S5vu449yFq4QR/nSDbeqRybubyt iKdOCo9hNKQd5kBa5eSp2y7jK2HGm47t4hxggzEev/lWaqYNFazQzZme9wvqOu5CxI 2w2FY4zEnwrK7g9wDE465WI9dMsFPxizcpn0hSfw= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from [192.168.1.101] ([212.95.5.238]) by mail.gmx.com (mrgmx104 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MCbIx-1hYNzT43Tn-009jZq; Thu, 09 May 2019 19:51:25 +0200 Subject: Re: bug#35564: 27.0.50; [PATCH] Tweak dired-do-shell-command warning about "wildcard" characters To: Drew Adams , =?UTF-8?Q?K=c3=a9vin_Le_Gouguec?= References: <87zho2cd4f.fsf@gmail.com> <071cc96c-1bf2-f331-8f9e-b3c54a7452da@gmx.at> <877eb3e5im.fsf@gmail.com> <9bd289fe-3623-4c45-4c4f-04c6668cae76@gmx.at> <9fc1129c-5377-4b56-ba6d-dce497140941@default> <877eb0ptiy.fsf@gmail.com> From: martin rudalics Message-ID: Date: Thu, 9 May 2019 19:51:28 +0200 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: de-DE Content-Transfer-Encoding: 7bit X-Provags-ID: V03:K1:6QXMBTrZ3SNfCrsH6NtjX+SnxwRoUorAM+9AgLcaGks+/6Rq75u mTXxT6NWekLrHc5J9CK/a9hxeyHuEU34/NaQFl3J/Q4FezQITw5KM70s/iKmiRGLhOaap7q 6y+D+/5swr/Xi6i6BW2kDp9SKmPLp1qVVBI+ejWIrMs/rEUtUjIATNHJ3NY4S8ZZy+j+L34 URdLfcCmvMiIrqNNc8A+Q== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:TrAsbbDW65c=:QpgIQ7b/Hcgrdju0gvdhv8 HCnj+ie+KlZ6HJuUgz9QLNO2Sv0auU4kybGxM5iZMI0K0uEr07XGdTeKKZkvyPjzBcvqO/89i ZJ5D6Pzu3f8M5DAOMi4AWSQiEYAOUIRIpuBHS2tg4d/iccrHR+uS74vhmuhiNYw5fdtbZJjcj YiQ8Qx18d4MRyV8SZD9iGaf3wOuCw4AkwrrBkOtNclm/RvPb6Sw752ouSet/kXcmhg6EDrqZ4 b5hK4L7yIi2uLAtMMu8So8Orc46JO/1TJwMhpbj4Mo6qF44JEklnaZGJkYP/EYU3p4lhWL0cm PpWD2c3jdha1tPWfHQz5GAP0BG7tj5CT0pvHrhXfK6ZMcsnh0gTi9woR4tqfNt4pghZRApt/R anrTGx0kDjUMwvoKwQmPOL2rI1+qzbP5NhxF9N8s78OplBndIeWay/8ilfxfpeD2mRmZAdnd8 IcbGY7R+BfGXexjcqEttyVfYyE405wZHArffC0OyKJf3KJinEHt67tDqw2AhjDUedqTXw1LNW TyXdk8a+/wOrZ3H2z2G6DFpBqB+nk5eRqiuZLyi7/PE6a5fQVptPK/J8oeXzc8lSDvrLJKOve RH3wKOIM3rGNpdH6WsqUfBSwz7+XccGOHqtftd/e7kFZavULFHQA1lpKtr0UEWsIAQ5R+LPAL xvoVIfn7V7XgCZP9lt8VX/oNSz3/aBtSvshRJj9ETAle6Qgvmt92UuvuxZYnxdkkFLoQLrtKm 7QZg6g6IFomLGXUEVO64wYGFi8HVzO0YfixIun/vgeZgfJCrSRNMoanjk83sm3eAMZSrjgc6E ItxXVF3msAIB2zAr9rhNp4kMW2NGHVhPEZjgZG7XgqNz1uD8kIjT8znsC6/Uy1s9xGz9GpgBG JA4fuH9Swjh3MHqOJDfdokj1HrriehzE7IUafgAVoFclhYf57o+ZfPz+WCpx72B9ZMChpfbxK p0Q+J3rubmA== X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) >> But I'm afraid we'll have to stick to what we have now. > > Why? Not sure what you mean. I mean that it won't be easy to convince others that we need a new face for propertizing prompts. > I would prefer that the two be separated. Tooltip text > is quite different from prompts in use cases and behavior. They are similar in the following aspect: Both prompts and tooltips are often displayed using toolkit functions. GTK tooltips are by default not propertized because the system doesn't accept any face properties for them. If Emacs used balloon tooltips on Windows, propertizing them would not be possible either. And both 'y-or-n-p' and 'yes-or-no-p', when implemented via dialog popups, don't adopt our text properties either. The question is now whether an application should accept the uniform appearance of such objects as prescribed by the toolkit used and as such obey the toolkit's look-and-feel or insist to use its own implementations. Emacs leaves that choice to its users. Which means that users are told things like "if you want this mode to behave as intended, you have to customize variables like 'use-dialog-box' or 'x-gtk-use-system-tooltips'". Nothing bad with that, but some users might be uncertain whether they should agree. In particular when such an option affects all sorts of tooltips or prompts. martin From debbugs-submit-bounces@debbugs.gnu.org Thu May 09 16:04:35 2019 Received: (at 35564) by debbugs.gnu.org; 9 May 2019 20:04:35 +0000 Received: from localhost ([127.0.0.1]:36527 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hOpHP-0008LB-Eq for submit@debbugs.gnu.org; Thu, 09 May 2019 16:04:35 -0400 Received: from aserp2130.oracle.com ([141.146.126.79]:39130) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hOpHN-0008Ky-O3 for 35564@debbugs.gnu.org; Thu, 09 May 2019 16:04:34 -0400 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x49JxCrR098810; Thu, 9 May 2019 20:04:27 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=aVjGFvQteozmOSoHWXUyw/hi3DzxOQ9APdXoidGpm+w=; b=0n+RzhV8HYh6iF2+YjYI9Tx+7RAdOq2Ez5CjhPFhbtGuvTp9V9km9do7LnwOEifTorgQ V7RWfUzYzTZg5ySkAuzjgSmlyn7SERoSGVtlSCm1a/tUz0UXZAjqqX6ZlMRdnPmnsUor H0f5wd7YcOBjy5WZ71mHU8UyqpLCFh/+rOiqEf1cVvdgWsZ9cWvoPkP4tcisGctTj3Fn auzw8UyUXUnkizmWpu594SNw1HM5WM+oBZWnStUsUa+zM9ugfyGSrn/lxBC6eSnunV0u /oRV7BPvze+HZ3mVXFq+UrgPxkTwC28Dg+D0jYiTXCdUNPyhfGV7x649p83d1pADKunZ DA== Received: from userp3020.oracle.com (userp3020.oracle.com [156.151.31.79]) by aserp2130.oracle.com with ESMTP id 2s94b6d948-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 09 May 2019 20:04:27 +0000 Received: from pps.filterd (userp3020.oracle.com [127.0.0.1]) by userp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x49K3Tqj109724; Thu, 9 May 2019 20:04:26 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userp3020.oracle.com with ESMTP id 2s94ah0ejq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 09 May 2019 20:04:26 +0000 Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x49K4Pu4005899; Thu, 9 May 2019 20:04:25 GMT MIME-Version: 1.0 Message-ID: Date: Thu, 9 May 2019 13:04:24 -0700 (PDT) From: Drew Adams To: martin rudalics , =?utf-8?B?S8OpdmluIExlIEdvdWd1ZWM=?= Subject: RE: bug#35564: 27.0.50; [PATCH] Tweak dired-do-shell-command warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <071cc96c-1bf2-f331-8f9e-b3c54a7452da@gmx.at> <877eb3e5im.fsf@gmail.com> <9bd289fe-3623-4c45-4c4f-04c6668cae76@gmx.at> <9fc1129c-5377-4b56-ba6d-dce497140941@default> <877eb0ptiy.fsf@gmail.com> In-Reply-To: X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4834.0 (x86)] Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9252 signatures=668686 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1905090114 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9252 signatures=668686 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1905090114 X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > >> But I'm afraid we'll have to stick to what we have now. > > > > Why? Not sure what you mean. >=20 > I mean that it won't be easy to convince others that we need a new > face for propertizing prompts. Why assume that? Who needs to be convinced? If we can't have a new face for this then I'd like to see non-minibuffer prompting have no face at all, by default. > > I would prefer that the two be separated. Tooltip text > > is quite different from prompts in use cases and behavior. >=20 > They are similar in the following aspect: Both prompts and tooltips > are often displayed using toolkit functions. That sounds like an implementation thing, not a user-level thing. And as I said, `x-show-tooltip' has no problem with showing propertized text. > GTK tooltips are by > default not propertized because the system doesn't accept any face > properties for them. If Emacs used balloon tooltips on Windows, > propertizing them would not be possible either. And both 'y-or-n-p' > and 'yes-or-no-p', when implemented via dialog popups, don't adopt our > text properties either. Oh, so `x-show-tooltip' only supports properties on some platforms (e.g. MS Windows)? If so, that's unfortunate. Yes, I don't expect window-dialogs to respect propertized text. Again, unfortunate - but livable. > The question is now whether an application should accept the uniform > appearance of such objects as prescribed by the toolkit used and as > such obey the toolkit's look-and-feel or insist to use its own > implementations. Emacs leaves that choice to its users. Which means > that users are told things like "if you want this mode to behave as > intended, you have to customize variables like 'use-dialog-box' or > 'x-gtk-use-system-tooltips'". Nothing bad with that, but some users > might be uncertain whether they should agree. In particular when such > an option affects all sorts of tooltips or prompts. Got it; thx. I would like to see Emacs allow, when possible, Emacsy things as much as possible. But I can understand that there can be some tradeoffs. From debbugs-submit-bounces@debbugs.gnu.org Sun Jun 09 07:08:52 2019 Received: (at 35564) by debbugs.gnu.org; 9 Jun 2019 11:08:52 +0000 Received: from localhost ([127.0.0.1]:54374 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hZvgx-0001n1-US for submit@debbugs.gnu.org; Sun, 09 Jun 2019 07:08:52 -0400 Received: from mail-wm1-f48.google.com ([209.85.128.48]:51337) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hZvgv-0001ml-Nv for 35564@debbugs.gnu.org; Sun, 09 Jun 2019 07:08:50 -0400 Received: by mail-wm1-f48.google.com with SMTP id 207so1026631wma.1 for <35564@debbugs.gnu.org>; Sun, 09 Jun 2019 04:08:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version; bh=hcuTuKk5ozc7mP++rUuLppfOeaAZQS4iv/G7FilvjJs=; b=W7e5n0TfYerWyu5gL9ZiCTOt99qnE1iTkHDPpYrX3TcBKUeSa74dVBI3QFLMBWIc2M WbNXxiODANjWhytsY7TKkD6ZMX/hW1iLQP+VqasJ+e7c9AI5nizwRhssodJZzmdHWvin dKFQfRpTQorkdtTWr3f28pYdoFEgvbH4b4CubGKYIQZdyuOBYvxI5yT8xrHBuAYLumuV OHm/IVk/lMsoh8psU7E+wle29bVsELMkyeW9PtWkdI+wIAqa8zWGE0zMPH7Kl7E2UACm sK9Cx/kTvm0iye/sLusGaBvPR55n7ohLIGbYUpjHdUY612Fayj9hjZ2kwNicPEXrXnl+ HIcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version; bh=hcuTuKk5ozc7mP++rUuLppfOeaAZQS4iv/G7FilvjJs=; b=SuHg7A7Gx+XtjNktkxD43zmHwSgT1HFXJMs/JQErJuZsWHpSMC3VrL6hBWcI7zoIav /fyUMwGHah43KlQYijvZHLfo69WpU43LvEWOvc17bUARDFWlS8pv5ZfGr9Cfxrj63dSs JMAtEcqdGy82le6wDMWRmbjAZLfDigcTgUIEBawVeh89GCKEcHGe2dZN6mQ/SdRo6QEO kHd99hIf+RoFVyBbnp5kJSdiRiP4eg02gvwxmqamSFuFoYkxKRB/e+RZkRpWI4374G51 DGELv977z+alC6QJJZJr8/E2sonTa5GUWw89+fRCKaDW+2uboZMErZJOt0FG0G5407hN J6fw== X-Gm-Message-State: APjAAAWBVfIuwDbHuK3bVE2GRswZjq3nPMFspYDfaBa7FRFkiNQSLznF FMi7AH3VQgu2i3DfqBGPJBHSH6Oi X-Google-Smtp-Source: APXvYqwVRqzv8aTiX+1S+lo2JzGSDnHDf6+2/cZzm7+HA9krTKoTXD9aS6b91RBtGkOUGNMgRXiGkA== X-Received: by 2002:a1c:9c4d:: with SMTP id f74mr9759282wme.156.1560078523505; Sun, 09 Jun 2019 04:08:43 -0700 (PDT) Received: from nc10-laptop (2a01cb04010fc800bcce02c98b58d624.ipv6.abo.wanadoo.fr. [2a01:cb04:10f:c800:bcce:2c9:8b58:d624]) by smtp.gmail.com with ESMTPSA id c5sm9054246wma.19.2019.06.09.04.08.42 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 09 Jun 2019 04:08:42 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: 35564@debbugs.gnu.org Subject: [PATCH v2] Tweak dired warning about "wildcard" characters Date: Sun, 09 Jun 2019 13:08:41 +0200 Message-ID: <87wohvf22u.fsf@gmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Hello, Here is my second attempt at solving this issue. To recap: dired-do-shell-command warns the user about non-isolated '*' and '?' characters since the function will not substitute them. It refers to these characters as "wildcards", which can be incorrect: they may be quoted or backslash-escaped, in which case the shell will not interpret them as wildcards. My main motivation to change this warning is that it trips my brain to have to answer "yes" ("yes, I want to use wildcards") when no wildcards are involved. I could not come up with a simple, self-sufficient rephrasing for the warning, so I decided to display the command itself as part of the warning prompt, highlighting the non-isolated characters. The first patch adjusts y-or-n-p so that it preserves the prompt's text properties. The second patch changes dired-do-shell-command's prompt. --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Preserve-text-properties-in-y-or-n-p-prompts.patch >From 1719809f75183dcc743f2bdf697c919ae859b82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:03:59 +0200 Subject: [PATCH 1/2] Preserve text properties in y-or-n-p prompts * lisp/subr.el (read--propertize-prompt): New function to append the prompt face to a string. (y-or-n-p): Use it instead of discarding potential text properties. --- lisp/subr.el | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lisp/subr.el b/lisp/subr.el index fd60ec87cc..1fcadc291c 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2334,6 +2334,9 @@ memory-limit ;;;; Input and display facilities. +(defun read--propertize-prompt (prompt) + (add-face-text-property 0 (length prompt) 'minibuffer-prompt t prompt)) + (defconst read-key-empty-map (make-sparse-keymap)) (defvar read-key-delay 0.01) ;Fast enough for 100Hz repeat rate, hopefully. @@ -2671,14 +2674,14 @@ y-or-n-p (let* ((scroll-actions '(recenter scroll-up scroll-down scroll-other-window scroll-other-window-down)) (key - (let ((cursor-in-echo-area t)) + (let ((cursor-in-echo-area t) + (prompt (if (memq answer scroll-actions) + prompt + (concat "Please answer y or n. " prompt)))) (when minibuffer-auto-raise (raise-frame (window-frame (minibuffer-window)))) - (read-key (propertize (if (memq answer scroll-actions) - prompt - (concat "Please answer y or n. " - prompt)) - 'face 'minibuffer-prompt))))) + (read--propertize-prompt prompt) + (read-key prompt)))) (setq answer (lookup-key query-replace-map (vector key) t)) (cond ((memq answer '(skip act)) nil) -- 2.20.1 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0002-Tweak-dired-warning-about-wildcard-characters.patch >From 69b8dfc60f8aca1a6f5358af6fdf60ce3c910cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:19:44 +0200 Subject: [PATCH 2/2] Tweak dired warning about "wildcard" characters Non-isolated '?' and '*' characters may be quoted, or backslash-escaped; we do not know for a fact that the shell will interpret them as wildcards. Rephrase the prompt and highlight the characters so that the user sees exactly what we are talking about. * lisp/dired-aux.el (dired--isolated-char-p) (dired--highlight-nosubst-char, dired--no-subst-prompt): New functions. (dired-do-shell-command): Use them. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p) (dired-test-highlight-metachar): Test the new functions. --- lisp/dired-aux.el | 49 +++++++++++++++++++++++++++++++++--- test/lisp/dired-aux-tests.el | 27 ++++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 51749acb21..dfb793324f 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -79,6 +79,49 @@ dired--star-or-qmark-p (funcall (if keep #'string-match-p #'string-match) x string)) regexps))) +(defun dired--isolated-char-p (command pos) + "Assert whether the character at POS is isolated within COMMAND. +A character is isolated if: +- it is surrounded by whitespace, the start of the command, or + the end of the command, +- it is surrounded by `\\=`' characters." + (let ((n (length command)) + (whitespace '(?\s ?\t))) + (or (= n 1) + (and (= pos 0) + (memq (elt command 1) whitespace)) + (and (= pos (1- n)) + (memq (elt command (1- pos)) whitespace)) + (and + (> pos 0) + (< pos (1- n)) + (let ((prev (elt command (1- pos))) + (next (elt command (1+ pos)))) + (or (and (memq prev whitespace) + (memq next whitespace)) + (and (= prev ?`) + (= next ?`)))))))) + +(defun dired--highlight-nosubst-char (command char) + "Highlight occurences of CHAR that are not isolated in COMMAND. +These occurences will not be substituted; they will be sent as-is +to the shell, which may interpret them as wildcards." + (save-match-data + (let ((highlighted (substring-no-properties command)) + (pos 0)) + (while (string-match (regexp-quote char) command pos) + (let ((start (match-beginning 0)) + (end (match-end 0))) + (unless (dired--isolated-char-p command start) + (add-face-text-property start end 'warning nil highlighted)) + (setq pos end))) + highlighted))) + +(defun dired--no-subst-prompt (command char) + (let ((highlighted-command (dired--highlight-nosubst-char command char)) + (prompt "Confirm--the highlighted characters will not be substituted:")) + (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + ;;;###autoload (defun dired-diff (file &optional switches) "Compare file at point with FILE using `diff'. @@ -759,11 +802,9 @@ dired-do-shell-command (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((need-confirm-p command "*") - (y-or-n-p (format-message - "Confirm--do you mean to use `*' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "*"))) ((need-confirm-p command "?") - (y-or-n-p (format-message - "Confirm--do you mean to use `?' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "?"))) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ccd3192792..77a4232aac 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,6 +114,33 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(ert-deftest dired-test-isolated-char-p () + (should (dired--isolated-char-p "?" 0)) + (should (dired--isolated-char-p "? " 0)) + (should (dired--isolated-char-p " ?" 1)) + (should (dired--isolated-char-p " ? " 1)) + (should (dired--isolated-char-p "foo bar ? baz" 8)) + (should (dired--isolated-char-p "foo -i`?`" 7)) + (should-not (dired--isolated-char-p "foo 'bar?'" 8)) + (should-not (dired--isolated-char-p "foo bar?baz" 7)) + (should-not (dired--isolated-char-p "foo bar?" 7))) + +(ert-deftest dired-test-highlight-metachar () + "Check that non-isolated meta-characters are highlighted" + (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (result (dired--highlight-nosubst-char command "?"))) + (should-not (text-property-not-all 1 14 'face nil result)) + (should (equal 'warning (get-text-property 15 'face result))) + (should-not (text-property-not-all 16 28 'face nil result)) + (should (equal 'warning (get-text-property 29 'face result))) + (should-not (text-property-not-all 30 39 'face nil result))) + (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") + (result (dired--highlight-nosubst-char command "*"))) + (should-not (text-property-not-all 1 10 'face nil result)) + (should (equal 'warning (get-text-property 11 'face result))) + (should-not (text-property-not-all 12 23 'face nil result)) + (should (equal 'warning (get-text-property 24 'face result))) + (should-not (text-property-not-all 25 29 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.20.1 --=-=-= Content-Type: text/plain Sample screenshot: --=-=-= Content-Type: image/png Content-Disposition: attachment; filename=dired-warning-highlight.png Content-Transfer-Encoding: base64 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 AElFTkSuQmCC --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable I am not sure these patches should be applied as-is. Some things I wonder about: 1. About read--propertize-prompt=E2=80=A6 1. Should the function return a copy of its argument instead of propertizing it directly? 2. Is it properly named? Does it fit in subr.el? I placed it there because I figured other users of read-char in subr.el could use it, e.g. read-char-choice. 2. dired-aux.el already contains some logic to detect isolated characters; I could not think of a way to re-use it, so I added my own functions to find *non*-isolated characters. I added unit tests for these new functions; still, there may be some redundancy there. WDYT? PS1: I am still absolutely open to simply rephrasing the prompt=E2=80=A6 I= just cannot come up with good alternatives. PS2: CC'ing Stefan to follow up on the discussion on emacs-devel. --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Wed Jun 12 08:23:22 2019 Received: (at 35564) by debbugs.gnu.org; 12 Jun 2019 12:23:22 +0000 Received: from localhost ([127.0.0.1]:60843 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hb2Hf-0003hu-W7 for submit@debbugs.gnu.org; Wed, 12 Jun 2019 08:23:22 -0400 Received: from mail-it1-f181.google.com ([209.85.166.181]:54368) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hb2Hd-0003hh-Mw for 35564@debbugs.gnu.org; Wed, 12 Jun 2019 08:23:18 -0400 Received: by mail-it1-f181.google.com with SMTP id m138so10382941ita.4 for <35564@debbugs.gnu.org>; Wed, 12 Jun 2019 05:23:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=pRdyNG5JpuS2Ub9Xw/ejRJDDHRRwMk8QlCSMmqmC66M=; b=FIj0a4RAsR8TouSYPeJEp/CS6U4Ty7QGtGLmn4ocP33Xd05nprPzBpFixKih+ujKVl M8a9X9+FDnqyBOoZxgN1g13Fojw/ZrrX19Ac9vJmLwrdnu5yHLvFXX6PEEmSCCot2dqr Z77A0IJzY430FR9Gt+kUyq4qhU4r4QvGv/Nrx+Rpj6mMtVKg0o9yOW2AuLggf3JGPLJK pCV1W1jgUwpcychmKoafm6QrypxSDjgJb2CjJECYXUJoiRyGwUXzBNkBNDV12kK7mfD8 N4BfkhBFotIcKvgyUsVq5nvfZBKGr+JkMoMuy/w56nFwRhL3PyCbKCW0e42nFjEr7Reo C6dA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=pRdyNG5JpuS2Ub9Xw/ejRJDDHRRwMk8QlCSMmqmC66M=; b=XTOGGjVYQr6GwY3oP/LRKrhtN0ZoQBc9137A2htiRSDlMXl6W8KwMyHDUYjcAnpIYf 7+p+IJT1sxxFWjltYCRQuNT8s5PerccIe/PbmXYr6vnAGSGJWJsYZ+oIPPCqqKbQgJYD KKKNFJJFBLvVq1RCYjmvzSuSemCMh7Zs8ssHPn0rdjYYa7tmLvAFzFO7DnoTeYD4i6KR zG1Laco2ljdG7jfX4b3RJtHdelzjVjFk1aEWyjieQkAieyH0/24UWwNcJia5YW6u+2GD uEtmxBG62wFeqN/HUL7szHwQ6hmzYub9el07DiMJUT3qWO966DYTygMipZuoYFNHMpcd Ctww== X-Gm-Message-State: APjAAAXZMRf5BiQrjaz2RSepiZrZFpl56Efyrk7oxDus4dCzmz/66pTm Fh44iKAAv4oHUL8Sf2F2cd4= X-Google-Smtp-Source: APXvYqzNb+9aueFgDbeGe7xT8ntBS+W9fCen9Vir+da1jDp9VjUlcDAP6oklr74eYZymKVmaX2xCow== X-Received: by 2002:a24:9f04:: with SMTP id c4mr21339250ite.176.1560342192044; Wed, 12 Jun 2019 05:23:12 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id y136sm2399696itc.37.2019.06.12.05.23.11 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 12 Jun 2019 05:23:11 -0700 (PDT) From: Noam Postavsky To: =?utf-8?Q?K=C3=A9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v2] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> Date: Wed, 12 Jun 2019 08:23:10 -0400 In-Reply-To: <87wohvf22u.fsf@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Sun, 09 Jun 2019 13:08:41 +0200") Message-ID: <87muinyoup.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) K=C3=A9vin Le Gouguec writes: > +(defun dired--isolated-char-p (command pos) > + "Assert whether the character at POS is isolated within COMMAND. > +A character is isolated if: > +- it is surrounded by whitespace, the start of the command, or > + the end of the command, > +- it is surrounded by `\\=3D`' characters." > + (let ((n (length command)) > + (whitespace '(?\s ?\t))) > + (or (=3D n 1) > + (and (=3D pos 0) > + (memq (elt command 1) whitespace)) > + (and (=3D pos (1- n)) > + (memq (elt command (1- pos)) whitespace)) > + (and > + (> pos 0) > + (< pos (1- n)) > + (let ((prev (elt command (1- pos))) > + (next (elt command (1+ pos)))) > + (or (and (memq prev whitespace) > + (memq next whitespace)) > + (and (=3D prev ?`) > + (=3D next ?`)))))))) I think this might be better expressed in regexp: (and (string-match (rx-to-string '(seq (or bos (in blank ?`)) (group (eval (string (aref command pos)))) (or eos (in blank ?`)))) command (max 0 (1- pos))) (=3D pos (match-beginning 1))) Although this gives different results for things like: (dired--isolated-char-p "?`foo`" 0) Do we care about that? (if yes, then that's a missing test case) > +(defun dired--highlight-nosubst-char (command char) > + "Highlight occurences of CHAR that are not isolated in COMMAND. > +These occurences will not be substituted; they will be sent as-is > +to the shell, which may interpret them as wildcards." > + (save-match-data > + (let ((highlighted (substring-no-properties command)) > + (pos 0)) > + (while (string-match (regexp-quote char) command pos) > + (let ((start (match-beginning 0)) > + (end (match-end 0))) > + (unless (dired--isolated-char-p command start) > + (add-face-text-property start end 'warning nil highlighted)) > + (setq pos end))) > + highlighted))) And perhaps the regexp above (if it's correct) can be integrated into this search? (maybe not though, since negation isn't straightforward in regexps) From debbugs-submit-bounces@debbugs.gnu.org Wed Jun 12 10:29:36 2019 Received: (at 35564) by debbugs.gnu.org; 12 Jun 2019 14:29:36 +0000 Received: from localhost ([127.0.0.1]:33778 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hb4Fr-00031J-Sl for submit@debbugs.gnu.org; Wed, 12 Jun 2019 10:29:36 -0400 Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:42482) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hb4Fp-000315-QF for 35564@debbugs.gnu.org; Wed, 12 Jun 2019 10:29:34 -0400 Received: from pmg1.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id 94A03100946; Wed, 12 Jun 2019 10:29:28 -0400 (EDT) Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id 659AE1007B5; Wed, 12 Jun 2019 10:29:27 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1560349767; bh=T29T5eljp+9Tvb8r5LZBNqmieNTKyTBwP+xy4FfozaA=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=pmeZ50/T1tgjON3x2IWrOQsJugBFFF7atkq1Q49uvmZCe0BuCYEqm/zb7fIDOJlPh RboT1XF8ZnLf1oGMcBSkXuNL/gx50NEAcObZoRWC1OaG98qjbPimcTd7zdeQ2rUGOB oPEBXeM2lwhcUCXY4YSYb7xY1zXfhHRuIMvSC/iNY7th++MFEuxd7EOuhBnrPmuuTg MaOwcK0aYdFwib0Km77CTkh+yCtI3MeneRf8r87SXQf986Gs5ZnVeAe6Esxqa6BMxI 7ywePD0jnhvrsLpl5n5NSJDL/UDLB8AhovmBIaoaZj9oqMvDkTeSMSZWFnFRCjsde2 hBKThbyjrUgnw== Received: from alfajor (cm-84.215.66.78.getinternet.no [84.215.66.78]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 9C945120C6E; Wed, 12 Jun 2019 10:29:26 -0400 (EDT) From: Stefan Monnier To: Noam Postavsky Subject: Re: bug#35564: [PATCH v2] Tweak dired warning about "wildcard" characters Message-ID: References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87muinyoup.fsf@gmail.com> Date: Wed, 12 Jun 2019 10:29:25 -0400 In-Reply-To: <87muinyoup.fsf@gmail.com> (Noam Postavsky's message of "Wed, 12 Jun 2019 08:23:10 -0400") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SPAM-INFO: Spam detection results: 0 ALL_TRUSTED -1 Passed through trusted hosts only via SMTP BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain X-SPAM-LEVEL: X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, =?windows-1252?Q?K=E9vin?= Le Gouguec X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > (rx-to-string '(seq (or bos (in blank ?`)) > (group (eval (string (aref command pos)))) > (or eos (in blank ?`)))) Can't we use `(... ,.. ..) instead of `eval`? Stefan From debbugs-submit-bounces@debbugs.gnu.org Thu Jun 13 02:19:45 2019 Received: (at 35564) by debbugs.gnu.org; 13 Jun 2019 06:19:45 +0000 Received: from localhost ([127.0.0.1]:34393 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbJ5N-00033s-2A for submit@debbugs.gnu.org; Thu, 13 Jun 2019 02:19:45 -0400 Received: from mail-wm1-f45.google.com ([209.85.128.45]:38843) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbJ5K-00033Z-VE for 35564@debbugs.gnu.org; Thu, 13 Jun 2019 02:19:43 -0400 Received: by mail-wm1-f45.google.com with SMTP id s15so8769183wmj.3 for <35564@debbugs.gnu.org>; Wed, 12 Jun 2019 23:19:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=zsvdYWX22aonVYDP5Kud9jJV2HTd1eM5798IUxtqloY=; b=HIJ5+jG/JnzLmi3yMsX/S2YQRSwy8pbjRI+6vmAhskYnwYLxBpnaZU171p1lx1PkTn DHVRzWy91n9wtd5IE68hQyycrJSWWBLCxAQHULlp+FvaX57HuF7x1IcXnZz25RQRfgSl ccSDbzuFVWIM/gn1gBW3MVarj2BcFiVujq1+MWZwmB8rrsvyJgJC1jPb9TvsJ+DFUYQh KHi8Ky3khvsbpSyqUCVooFy9I4tuwizTnFZVVPfSB+TZ+bmmfQJYJ7IJvWPBrSSOH4xV E0dIlOSrB3+LGDVqlrF6XmPX6LEwLpRS+hCKMffYmULlzd30lmjypgtt1bW4QtzNnUpW 6FMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=zsvdYWX22aonVYDP5Kud9jJV2HTd1eM5798IUxtqloY=; b=KsqUWbNe7VPNZiTfkJH5ux+tSny6kIpOzml2jucovxjzYmwpDVKlez0nO9Wh89lSJH FQIPfQO9lxky/a0YWx5NdkeBgNbTIKRWISLCRHjjDpqiaubtI9QenzT07snvS41Yn/kd 2XGK5Y1CZqqeJP0ukRCBkJKGCVqMaSGk9rk9VoXG/oLMEkxsQcrbOVdzmYNqo6U1zDAS kICPvxMR0NgwXURO9+A5hmi7cQK45fWpNzyhp/EUfxwxIN0Xrxp9v3izEK/EvPEzTHlB FBicLR9jpBrKFgA7pHfpL3dxeaDXHrh+rO8DritVY9x6ryAZ8bkKmC2ifxIeozhxOEjM ZgEQ== X-Gm-Message-State: APjAAAW2OM90YPtsmsuulYLKbHUYEFg9SFT1Thn7ubYdR6+yIt4Vn7uI p6POp1RKfN3HBvFQ0FKIDxo= X-Google-Smtp-Source: APXvYqxZwQeW7C+qfo+ZN9j5bAIK60hfciZsExRfa3l2T9yfYDaiEB/8zU7u0ySkDSJxT0pBflla8A== X-Received: by 2002:a1c:6242:: with SMTP id w63mr2225489wmb.161.1560406776977; Wed, 12 Jun 2019 23:19:36 -0700 (PDT) Received: from my-little-tumbleweed (71.142.13.109.rev.sfr.net. [109.13.142.71]) by smtp.gmail.com with ESMTPSA id r2sm1786231wma.26.2019.06.12.23.19.35 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 12 Jun 2019 23:19:36 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Noam Postavsky Subject: Re: bug#35564: [PATCH v2] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87muinyoup.fsf@gmail.com> Date: Thu, 13 Jun 2019 08:19:33 +0200 In-Reply-To: <87muinyoup.fsf@gmail.com> (Noam Postavsky's message of "Wed, 12 Jun 2019 08:23:10 -0400") Message-ID: <87tvcum2h6.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Noam Postavsky writes: > I think this might be better expressed in regexp: I guess it is; I just tend to get superstitious about messing with match data. > Although this gives different results for things like: > > (dired--isolated-char-p "?`foo`" 0) > > Do we care about that? (if yes, then that's a missing test case) I think we do care; if I look at what the existing code says, (dired--star-or-qmark-p "?`foo`" "?") ;; =3D> nil Off the top of my head, this is the best I can come up with to satisfy this edge case: (defun dired--isolated-char-p (command pos) "Assert whether the character at POS is isolated within COMMAND. A character is isolated if: - it is surrounded by whitespace, the start of the command, or the end of the command, - it is surrounded by `\\=3D`' characters." (let ((start (max 0 (1- pos))) (char (string (aref command pos)))) (and (or (string-match (rx-to-string '(seq (or bos blank) (group char) (or eos blank))) command start) (string-match (rx-to-string '(seq ?` (group char) ?`)) command start)) (=3D pos (match-beginning 1))))) > And perhaps the regexp above (if it's correct) can be integrated into > this search? (maybe not though, since negation isn't straightforward in > regexps) I will look into that. Stefan Monnier writes: > Can't we use `(... ,.. ..) instead of `eval`? > > > Stefan That works too from what I tested, although it's not necessary anymore with the new version above. Thank you both for the review! I will come back with an updated patch (with the new test case) Some Time Later=E2=84=A2. From debbugs-submit-bounces@debbugs.gnu.org Thu Jun 13 03:59:10 2019 Received: (at 35564) by debbugs.gnu.org; 13 Jun 2019 07:59:10 +0000 Received: from localhost ([127.0.0.1]:34458 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbKda-0005qI-2z for submit@debbugs.gnu.org; Thu, 13 Jun 2019 03:59:10 -0400 Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:53577) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbKdY-0005q2-2N for 35564@debbugs.gnu.org; Thu, 13 Jun 2019 03:59:08 -0400 Received: from pmg1.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id A16381009AF; Thu, 13 Jun 2019 03:59:02 -0400 (EDT) Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id 2B8C810087A; Thu, 13 Jun 2019 03:59:01 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1560412741; bh=/yFrZKACvdeJaH75m86elSLhSnhP8Vd6joAFvg5cZBo=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=B6OdWrwZWTCG5wqudMEOh3e/nR5zGf1CR9VSFxuWXmQIbGaEgdy/qtz7NN6RoRYun PFw7V4gXa6RIF7tM1xocKsbqGZUAMzuRUXTli4V+L84FW7Hcv5WFm6Lfvs7APWo/9e mzEv0Y5Upqen/c06pFdEpu9WHRkA3aSjJIzc5hBPO2cmycgW7X7nIC7I/H2IhSqkX7 hrKC2QINeCIrthV6WW2X6NNfgwG9d/Qv1AAfnCt9bTLcT4bheoxnj6YZxCX1FEMfpI ceQCdRO+cO+0Edp8RQJ06Qwg2vuTtbaeY4GKktMteyktmiXFx46tUKbRbdSWsIU4/v ud35qGenr9dLw== Received: from alfajor (cm-84.215.66.78.getinternet.no [84.215.66.78]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 38CC0120AD0; Thu, 13 Jun 2019 03:59:00 -0400 (EDT) From: Stefan Monnier To: =?windows-1252?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v2] Tweak dired warning about "wildcard" characters Message-ID: References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87muinyoup.fsf@gmail.com> <87tvcum2h6.fsf@gmail.com> Date: Thu, 13 Jun 2019 03:58:58 -0400 In-Reply-To: <87tvcum2h6.fsf@gmail.com> (=?windows-1252?Q?=22K=E9vin?= Le Gouguec"'s message of "Thu, 13 Jun 2019 08:19:33 +0200") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SPAM-INFO: Spam detection results: 0 ALL_TRUSTED -1 Passed through trusted hosts only via SMTP BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain X-SPAM-LEVEL: X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Noam Postavsky X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > I guess it is; I just tend to get superstitious about messing with match > data. Instead, you should get superstitious about using the match data too far from the corresponding match. Stefan From debbugs-submit-bounces@debbugs.gnu.org Thu Jun 13 12:53:17 2019 Received: (at 35564) by debbugs.gnu.org; 13 Jun 2019 16:53:17 +0000 Received: from localhost ([127.0.0.1]:36033 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbSyT-0000zT-4Y for submit@debbugs.gnu.org; Thu, 13 Jun 2019 12:53:17 -0400 Received: from mail-io1-f54.google.com ([209.85.166.54]:41320) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hbSyQ-0000zD-V6 for 35564@debbugs.gnu.org; Thu, 13 Jun 2019 12:53:15 -0400 Received: by mail-io1-f54.google.com with SMTP id w25so18432783ioc.8 for <35564@debbugs.gnu.org>; Thu, 13 Jun 2019 09:53:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=8rmcSgjvgHMDVwbuFz19706fMkOVpeOcYPSlCPJ3W/4=; b=g9sDfy2qubqsg0RtHRvZ3vzH90tLjTmRbKXtAyg/eRP+UPCpj6iDVANk8Ol/+IFP4L cdF5Je9Ct3ODU8EHqS/Ch1Iyxwn7ik8gKQSiZNhx5cTKWwv+sDIinWffbmq/pKwdcdHH pygbc/aMDWtN/s8ZBgu6EcgTgj7GpbU1y9VqHAB1YTsZ5J3FZd8fQ2QTbnorXv39yAA5 ABL+tUNDlAEV9LuD6GLL1yfWUbzneR/wypwDRzPeJZiF/im1lxoMWxv3maVCpvyklEok U5fX8+JNER9ljqsO2BCSlbYF/n/Ohezv6gsTkEAJqnshr88X7kuRb8Z1q2FpACKD93Ee D9Lw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=8rmcSgjvgHMDVwbuFz19706fMkOVpeOcYPSlCPJ3W/4=; b=MTAQkrmSog32cE4NNhHcUqFYA0lg0iYTN0i6nObb9Jh7Va/lpg9M1fJAmpdZo+QefQ L8WcG+jNBbxDPYIgdnFfY77EN+HkQr2N5sbiawW7CgymWNezDQwVbRwQ66tnjRKLLjfC +VYSTq3tfEbY3yK/qYnFXgtHqz0GBkAsCtz8VXpqyFZmSSx4XKIR8n05mVRHO2EiRHaq TSLqIxs8apKS3YCo5uSYloKLzK1SHiJdz/LxK0cdqYkk8CtnTsxC1Jfor2mxviQEWFrc cEedKMMZ81dcLlSsXQ3W+gm7prdE5e6zEE8lDgKEKDLXSWucV4ql31bhBOrI2cje5LOw 4x3g== X-Gm-Message-State: APjAAAU9WQuzmJBKBfwxSJkYLUUgsqnuujTtgXgIRHgAVZe92093FTNC qllfcVQfma21SVTT3+YUARc= X-Google-Smtp-Source: APXvYqwaH5vHYj8rHFTRf27HdotDQoF1+jpKz4fzgPGQF7Z2dGGkZgSXYjb9SQ2FUGezAbYWN+QS1Q== X-Received: by 2002:a5d:9282:: with SMTP id s2mr10967549iom.36.1560444789263; Thu, 13 Jun 2019 09:53:09 -0700 (PDT) Received: from vhost2 (CPE001143542e1f-CMf81d0f809fa0.cpe.net.cable.rogers.com. [99.230.51.196]) by smtp.gmail.com with ESMTPSA id j13sm403966ioa.76.2019.06.13.09.53.08 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 13 Jun 2019 09:53:08 -0700 (PDT) From: npostavs@gmail.com To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v2] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87muinyoup.fsf@gmail.com> <87tvcum2h6.fsf@gmail.com> Date: Thu, 13 Jun 2019 12:53:08 -0400 In-Reply-To: <87tvcum2h6.fsf@gmail.com> (=?iso-8859-1?Q?=22K=E9vin?= Le Gouguec"'s message of "Thu, 13 Jun 2019 08:19:33 +0200") Message-ID: <85r27x2zrf.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1.92 (windows-nt) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > > I think we do care; if I look at what the existing code says, > > (dired--star-or-qmark-p "?`foo`" "?") > ;; => nil > (let ((start (max 0 (1- pos))) > (char (string (aref command pos)))) > (rx-to-string '(seq (or bos blank) > (group char) `char' in this context translates to the "." regexp (i.e., any character). Yeah it's a bit weird. I have a patch in mind to remove the need for eval or rx-to-string. I'll send in a few days (to a new bug, it's getting off-topic here). Meanwhile, I suggest: (let ((start (max 0 (1- pos))) (char (aref command pos))) (and (string-match (rx-to-string `(or (seq (or bos blank) (group-n 1 ,char) (or eos blank)) (seq ?` (group-n 1 ,char) ?`))) command start) (= pos (match-beginning 1)))) From debbugs-submit-bounces@debbugs.gnu.org Tue Jun 18 04:53:09 2019 Received: (at 35564) by debbugs.gnu.org; 18 Jun 2019 08:53:09 +0000 Received: from localhost ([127.0.0.1]:43741 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hd9rZ-00036X-J2 for submit@debbugs.gnu.org; Tue, 18 Jun 2019 04:53:09 -0400 Received: from mail-wm1-f54.google.com ([209.85.128.54]:51731) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hd9rX-000369-Jb for 35564@debbugs.gnu.org; Tue, 18 Jun 2019 04:53:08 -0400 Received: by mail-wm1-f54.google.com with SMTP id 207so2280911wma.1 for <35564@debbugs.gnu.org>; Tue, 18 Jun 2019 01:53:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=FKGQhl+yQ10JJFBKqo1jqF5Sf6QS2DVtkgA8JzXhRis=; b=YewHB5Ir7ZzU7PPFSzq1kTI+jQQ6JHVbmXHEmeENBkz9FcNHUFn2k7VFA4jFoL7IaY uNRA87Hhuupbfe5VrXKqck/6wg4gYD1YXGrjtQGZ5mA3tO5XXkUIBL6LrnRH0sxxzADe emWFrCKMvJAsiPabfvDdJjqUy2AWq7OcU5EbpyuqIH+PrdLGS4/SVoQAn/IOz9giVRu3 6HGwBH9LXc6wyGrWzIBddPfBINO2U0CuEU5ocxYWULACqBBqLlNX5d5rKWvXqs3fAFyz qTfjOabHdmVWjhCa/B5Vu77g9OwOJdMM+VuA1O9vox7EZNY/IkUlYmkH8Do8McD94I+q rtww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=FKGQhl+yQ10JJFBKqo1jqF5Sf6QS2DVtkgA8JzXhRis=; b=ByE39FJ1j8nbv8jkcgPkq0oQYKYWnhoBFXmZe1F5qpDxkoUy/TG0eEQzhSGl9Fg7+K XRpSH8KDWfrGl3tv0QeSDsK/SemT3IcnuFZJMnYEJLHBpfaBlHNHaOsG0xCnoG4Mmb2C 1EM1PJh4eHGSInwsTpL2QTb67xCeVmc3q6If8a1VUPNNEbawZ0MW/a7x6yRIKR6oDioW DBExErLod6Ax2m8ynqiOGxaFqfKC56XkkdVLHvUCVJaAhFxgXjTUR6QAOQyv7wQ4UdEO i+r2MTY7DXFn8J2zKBJQQLtqa6Wlb7vKEWtzxWTyYG593uZ2vDKoLnibgmJamFh4xBvz Im2g== X-Gm-Message-State: APjAAAUnxBuqbbNTbrPXb8KfRAbzVRMpZi/ZXX2Imv5RS5Z6PUKHE+eN XQiBb+kg8MINAq7eLqEr0NU= X-Google-Smtp-Source: APXvYqwNS9DXB1+brvknJn9fv98cdddVBkIvLnD0BlX2eS57Oe+fV411xvfocIns/gXQOqKiybo5Rg== X-Received: by 2002:a7b:cb94:: with SMTP id m20mr2373088wmi.144.1560847980704; Tue, 18 Jun 2019 01:53:00 -0700 (PDT) Received: from my-little-tumbleweed (71.142.13.109.rev.sfr.net. [109.13.142.71]) by smtp.gmail.com with ESMTPSA id g5sm15121962wrp.29.2019.06.18.01.52.59 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Tue, 18 Jun 2019 01:52:59 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: npostavs@gmail.com Subject: Re: bug#35564: [PATCH v2] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87muinyoup.fsf@gmail.com> <87tvcum2h6.fsf@gmail.com> <85r27x2zrf.fsf@gmail.com> Date: Tue, 18 Jun 2019 10:52:58 +0200 In-Reply-To: <85r27x2zrf.fsf@gmail.com> (npostavs@gmail.com's message of "Thu, 13 Jun 2019 12:53:08 -0400") Message-ID: <877e9jp95h.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) npostavs@gmail.com writes: > (rx-to-string `(or (seq (or bos blank) > (group-n 1 ,char) > (or eos blank)) > (seq ?` (group-n 1 ,char) ?`))) Ah! Thanks for teaching me about \(?NUM: ... \), I did not know this Elisp extension. This makes the whole thing much more readable. For a minute I thought that maybe this patch should also add (require 'rx) somewhere in dired-aux.el, but AFAICT this is not necessary since rx-to-string is autoloaded=E2=80=A6 Do I understand correctly? Thanks again for the review, and for your efforts with bug#36237. (And thank you Stefan for your advice on being superstitious about the right things :) ) From debbugs-submit-bounces@debbugs.gnu.org Tue Jun 18 20:12:14 2019 Received: (at 35564) by debbugs.gnu.org; 19 Jun 2019 00:12:14 +0000 Received: from localhost ([127.0.0.1]:45753 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hdOD0-0005OX-DV for submit@debbugs.gnu.org; Tue, 18 Jun 2019 20:12:14 -0400 Received: from mail-io1-f48.google.com ([209.85.166.48]:37820) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hdOCy-0005OI-Py for 35564@debbugs.gnu.org; Tue, 18 Jun 2019 20:12:13 -0400 Received: by mail-io1-f48.google.com with SMTP id e5so34127964iok.4 for <35564@debbugs.gnu.org>; Tue, 18 Jun 2019 17:12:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=GGPf466sOMiONq18O3a3ZhMv3yEAUu0myOEqw5BZzxs=; b=J4vR+MF+aln9s7KLwuhVc6ayj0NlSep8zFlLdGuNZN2j2NeVFZqUOVoe/yGqg2lQnQ 6raMSIOnm1KFUZ4kJOr6Dlsh+0hR3/yzNkeRP2hpaMMTu/td12NZFksOgXtRwLaFhjXT aOIh6ZZSuMnGzC5+ANnoEwUmM0Ib+Zbw4i3dyjyZJabrWDe8WkYQsMUVzWE1inSvJq/F AIPd0Z4xFOfq3Z2+ImtjvsU11+tZYuV3FFIvz9OUk3hhlbzUzL0wo/ZOPc30+3DbZF0Y 8v/EAltZWVzjMZBEqZ2ZLfLpJKaY2ZE6v+Vs968cvIUnxxRBkamDnZAmmQK6L+3MrBau ft/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=GGPf466sOMiONq18O3a3ZhMv3yEAUu0myOEqw5BZzxs=; b=MyZirt0r/AdD+VTftrxtIN/01ZdC7plSns0biFPPlSmRU7KwGuQsYinMoVlZEaVT+R pqY9Kpfhb0QrkInstxLxyq4KZpoTdQw+1AzZ9TDUGKXriE99eH1Gf9EhbWtXRbEpKqGa L9fGKUtNsRUvYNkMTnykIqWR/bMFTRa9QcO5F3h82iC+f7gMrfSjN2PBASEUgEO6lwvl rO8xE/qv+J6wGdcoDPlBko5PSlyS3GxmHyAzHdd3bPmUd5LwrcWVgR+8Ld851C4bYwm2 3xxl2c0KsHRrQ7tdcrm15iS6Yrv9Hy9YcGaqJgDeH7xIW0sCbiEG9Td4wK2SxsYvMqnM 60PA== X-Gm-Message-State: APjAAAUREzOjEqW6oD2f70VH6f+dv/HjHthBk8/odv2h/+FrSedsyoin lJP7zKFThmyOI0b9MULtNN8= X-Google-Smtp-Source: APXvYqz+D7b6d88Na4xBxoTEAofb3l6fxIJ2/Vir00yFgGdQqOrH9ThPdORZrpj09IQ1T4vjbo558g== X-Received: by 2002:a6b:ce19:: with SMTP id p25mr874065iob.201.1560903125151; Tue, 18 Jun 2019 17:12:05 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id y20sm13347185ion.77.2019.06.18.17.12.04 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 18 Jun 2019 17:12:04 -0700 (PDT) From: Noam Postavsky To: =?utf-8?Q?K=C3=A9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v2] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87muinyoup.fsf@gmail.com> <87tvcum2h6.fsf@gmail.com> <85r27x2zrf.fsf@gmail.com> <877e9jp95h.fsf@gmail.com> Date: Tue, 18 Jun 2019 20:12:03 -0400 In-Reply-To: <877e9jp95h.fsf@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Tue, 18 Jun 2019 10:52:58 +0200") Message-ID: <87wohiwi0c.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) K=C3=A9vin Le Gouguec writes: > For a minute I thought that maybe this patch should also add (require > 'rx) somewhere in dired-aux.el, but AFAICT this is not necessary since > rx-to-string is autoloaded=E2=80=A6 Do I understand correctly? Yes, that's correct. From debbugs-submit-bounces@debbugs.gnu.org Wed Jun 26 02:16:56 2019 Received: (at 35564) by debbugs.gnu.org; 26 Jun 2019 06:16:56 +0000 Received: from localhost ([127.0.0.1]:34128 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hg1El-0002aS-Kq for submit@debbugs.gnu.org; Wed, 26 Jun 2019 02:16:56 -0400 Received: from mail-wm1-f54.google.com ([209.85.128.54]:54074) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hg1Ei-0002aB-7b for 35564@debbugs.gnu.org; Wed, 26 Jun 2019 02:16:52 -0400 Received: by mail-wm1-f54.google.com with SMTP id x15so752714wmj.3 for <35564@debbugs.gnu.org>; Tue, 25 Jun 2019 23:16:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=TdhAek/43zGPzcNCsmaUD2UpphhMrHwFFXzpIg9oHUw=; b=LBiyMDTLzvVnxrSFgZA5mtE76peq8YGIIK3nWCGlXyT6V0IJWpP14df/3FvrQNkgar BlaKAChX1giwLYXz3SHFkqKspY2wV/1EZSh2X3+tG/3aKBDQ8ZLZGb3kX7XqdhnOacny Yr+xypHz+isg510Dvsv2tmefEQT+EZgcYL1HGEegtV932+NprUhFy/wfOf0D8Lf85Upu OBaoBns9XQLLIxTleqMosS36HYfgNoj13DjsbAuyvtWumGR2rinO69uO9VcF1Si8vRUw Rau6EKasstVL456Ant4s2RnGD2k3R0lf1fIX6zuetnO2pYujmPeJu7M5AHYRaXHr0HrE u5TA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=TdhAek/43zGPzcNCsmaUD2UpphhMrHwFFXzpIg9oHUw=; b=RJQzbd8dOyM/N5m+Gp4zXep+7t//1KqRp8PROhqr4Zxi/gZ0fIoPjVtHVpQVr+TzUT uOt4JUjb8oMg9HUM6xeN+OD4UEYkyVtgFtpf9V4CygpKOd4+pllFu1QSB828gDCqtdEG 00nXO6IiJ97FgVGTmf+MNpH5RTlYJ/uCmapdXjdWHbAyufWK6TTRJ/WN4lDfi3/PmdZT VvMzKEhetTxcW1Q+mAV9IxVVlVWHJzG2RZ2TXGz3IW6v3fs4eDO2mbypVWCwrB9mSV+P +nDand/V6vu6a6gpRGhRtp6V4cEJQFWHNc1hlWe1kh4Q8lhKXcShIFP3FUJzzBY138+G 42Jg== X-Gm-Message-State: APjAAAXPnhPE7KeS3MiNaE6l9N3klQqeRceaS+5zKaykCqFviFBCpn8H YZP84Danry/9Sm7Xko0N4GA= X-Google-Smtp-Source: APXvYqz1tZo3wWuzaznVf8ipPiZEE6oVN3aFeC2IUrpSGYAur2Bxb9Pz2zQpvX0nRmZS6qnSKfjfLg== X-Received: by 2002:a1c:a654:: with SMTP id p81mr1209986wme.36.1561529806139; Tue, 25 Jun 2019 23:16:46 -0700 (PDT) Received: from my-little-tumbleweed (71.142.13.109.rev.sfr.net. [109.13.142.71]) by smtp.gmail.com with ESMTPSA id g19sm961934wmg.10.2019.06.25.23.16.44 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Tue, 25 Jun 2019 23:16:45 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: 35564@debbugs.gnu.org Subject: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> Date: Wed, 26 Jun 2019 08:16:44 +0200 In-Reply-To: <87wohvf22u.fsf@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Sun, 09 Jun 2019 13:08:41 +0200") Message-ID: <87h88cvpkj.fsf_-_@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Stefan Monnier , Noam Postavsky X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain And here is the third set of patches. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Preserve-text-properties-in-y-or-n-p-prompts.patch >From d2892b05f08348bbc3eea770a92f7cf735a88cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:03:59 +0200 Subject: [PATCH 1/2] Preserve text properties in y-or-n-p prompts * lisp/subr.el (read--propertize-prompt): New function to append the prompt face to a string. (y-or-n-p): Use it instead of discarding potential text properties. --- lisp/subr.el | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lisp/subr.el b/lisp/subr.el index baff1e909a..67c4f1da3a 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2334,6 +2334,9 @@ memory-limit ;;;; Input and display facilities. +(defun read--propertize-prompt (prompt) + (add-face-text-property 0 (length prompt) 'minibuffer-prompt t prompt)) + (defconst read-key-empty-map (make-sparse-keymap)) (defvar read-key-delay 0.01) ;Fast enough for 100Hz repeat rate, hopefully. @@ -2671,14 +2674,14 @@ y-or-n-p (let* ((scroll-actions '(recenter scroll-up scroll-down scroll-other-window scroll-other-window-down)) (key - (let ((cursor-in-echo-area t)) + (let ((cursor-in-echo-area t) + (prompt (if (memq answer scroll-actions) + prompt + (concat "Please answer y or n. " prompt)))) (when minibuffer-auto-raise (raise-frame (window-frame (minibuffer-window)))) - (read-key (propertize (if (memq answer scroll-actions) - prompt - (concat "Please answer y or n. " - prompt)) - 'face 'minibuffer-prompt))))) + (read--propertize-prompt prompt) + (read-key prompt)))) (setq answer (lookup-key query-replace-map (vector key) t)) (cond ((memq answer '(skip act)) nil) -- 2.21.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-Tweak-dired-warning-about-wildcard-characters.patch >From bf49a90f9bf5c03e159dd2377da079e195258ea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:19:44 +0200 Subject: [PATCH 2/2] Tweak dired warning about "wildcard" characters Non-isolated '?' and '*' characters may be quoted, or backslash-escaped; we do not know for a fact that the shell will interpret them as wildcards. Rephrase the prompt and highlight the characters so that the user sees exactly what we are talking about. * lisp/dired-aux.el (dired--isolated-char-p) (dired--highlight-nosubst-char, dired--no-subst-prompt): New functions. (dired-do-shell-command): Use them. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p) (dired-test-highlight-metachar): Test the new functions. --- lisp/dired-aux.el | 42 ++++++++++++++++++++++++++++++++---- test/lisp/dired-aux-tests.el | 28 ++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 5e4ec4d1ec..079e4f102f 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -79,6 +79,42 @@ dired--star-or-qmark-p (funcall (if keep #'string-match-p #'string-match) x string)) regexps))) +(defun dired--isolated-char-p (command pos) + "Assert whether the character at POS is isolated within COMMAND. +A character is isolated if: +- it is surrounded by whitespace, the start of the command, or + the end of the command, +- it is surrounded by `\\=`' characters." + (let ((start (max 0 (1- pos))) + (char (string (aref command pos)))) + (and (string-match + (rx (or (seq (or bos blank) + (group-n 1 (literal char)) + (or eos blank)) + (seq ?` (group-n 1 (literal char)) ?`))) + command start) + (= pos (match-beginning 1))))) + +(defun dired--highlight-nosubst-char (command char) + "Highlight occurences of CHAR that are not isolated in COMMAND. +These occurences will not be substituted; they will be sent as-is +to the shell, which may interpret them as wildcards." + (save-match-data + (let ((highlighted (substring-no-properties command)) + (pos 0)) + (while (string-match (regexp-quote char) command pos) + (let ((start (match-beginning 0)) + (end (match-end 0))) + (unless (dired--isolated-char-p command start) + (add-face-text-property start end 'warning nil highlighted)) + (setq pos end))) + highlighted))) + +(defun dired--no-subst-prompt (command char) + (let ((highlighted-command (dired--highlight-nosubst-char command char)) + (prompt "Confirm--the highlighted characters will not be substituted:")) + (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + ;;;###autoload (defun dired-diff (file &optional switches) "Compare file at point with FILE using `diff'. @@ -759,11 +795,9 @@ dired-do-shell-command (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((need-confirm-p command "*") - (y-or-n-p (format-message - "Confirm--do you mean to use `*' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "*"))) ((need-confirm-p command "?") - (y-or-n-p (format-message - "Confirm--do you mean to use `?' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "?"))) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ccd3192792..80b6393931 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,6 +114,34 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(ert-deftest dired-test-isolated-char-p () + (should (dired--isolated-char-p "?" 0)) + (should (dired--isolated-char-p "? " 0)) + (should (dired--isolated-char-p " ?" 1)) + (should (dired--isolated-char-p " ? " 1)) + (should (dired--isolated-char-p "foo bar ? baz" 8)) + (should (dired--isolated-char-p "foo -i`?`" 7)) + (should-not (dired--isolated-char-p "foo `bar`?" 9)) + (should-not (dired--isolated-char-p "foo 'bar?'" 8)) + (should-not (dired--isolated-char-p "foo bar?baz" 7)) + (should-not (dired--isolated-char-p "foo bar?" 7))) + +(ert-deftest dired-test-highlight-metachar () + "Check that non-isolated meta-characters are highlighted" + (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (result (dired--highlight-nosubst-char command "?"))) + (should-not (text-property-not-all 1 14 'face nil result)) + (should (equal 'warning (get-text-property 15 'face result))) + (should-not (text-property-not-all 16 28 'face nil result)) + (should (equal 'warning (get-text-property 29 'face result))) + (should-not (text-property-not-all 30 39 'face nil result))) + (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") + (result (dired--highlight-nosubst-char command "*"))) + (should-not (text-property-not-all 1 10 'face nil result)) + (should (equal 'warning (get-text-property 11 'face result))) + (should-not (text-property-not-all 12 23 'face nil result)) + (should (equal 'warning (get-text-property 24 'face result))) + (should-not (text-property-not-all 25 29 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.21.0 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable The first patch is unchanged (it adjusts y-or-n-p so that the prompt's text properties are preserved), the second patch uses the new (literal=C2=A0=E2=80=A6) feature from rx and adds a test case for dired--isolated-char-p[1]. Quoting my previous email: > Some things I wonder about: >=20 > 1. About read--propertize-prompt=E2=80=A6 >=20 > 1. Should the function return a copy of its argument instead of > propertizing it directly? >=20 > 2. Is it properly named? Does it fit in subr.el? I placed it there > because I figured other users of read-char in subr.el could use > it, e.g. read-char-choice. >=20 > 2. dired-aux.el already contains some logic to detect isolated > characters; I could not think of a way to re-use it, so I added my > own functions to find *non*-isolated characters. I added unit tests > for these new functions; still, there may be some redundancy there. Thank you for your time. [1] (should-not (dired--isolated-char-p "foo `bar`?" 9)) --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Wed Jun 26 09:28:05 2019 Received: (at 35564) by debbugs.gnu.org; 26 Jun 2019 13:28:05 +0000 Received: from localhost ([127.0.0.1]:34512 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hg7y1-0006nG-1z for submit@debbugs.gnu.org; Wed, 26 Jun 2019 09:28:05 -0400 Received: from aserp2120.oracle.com ([141.146.126.78]:34888) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hg7xz-0006mn-8f for 35564@debbugs.gnu.org; Wed, 26 Jun 2019 09:28:03 -0400 Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5QDOGRE147630; Wed, 26 Jun 2019 13:27:57 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=kMgzkNu8QSSr+gd7aSOLkfoyhWPHmaXHRMvQSMkoUxA=; b=XlVtCAATC++/zckpYiFJtaeB0dJniRqXOFfy/QEoyZkDzKKkGzmEvC3Np/YrE7CI+e0p MgbqqOiKGvuXNlXq8YQ3ANELoVkIKZUnUGC9NmEoG/26qJXE2bFA34U3PFWnnaIjeVBh ZHHAIja3T08VtT64yUTzVxLK85RplN0Hk5fQcdmhX+NfV5+RxAmcPl8WKf9NE3cWpBpU Jh13QN6HE2v8rNJ8Biku0qRvqblLYM+RMXnkpGzegcAieEGm+UuBnBZke+wj0vgI2dyT qa+ZbjWv9bVWR1u+a3vTwjbfvrBVaNla/3au2rjblLhiNi4daRUZo3vb5Yp38WNBGSa6 oQ== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by aserp2120.oracle.com with ESMTP id 2t9c9ptatm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 26 Jun 2019 13:27:57 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5QDRegS091788; Wed, 26 Jun 2019 13:27:57 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserp3020.oracle.com with ESMTP id 2t9p6usahq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 26 Jun 2019 13:27:56 +0000 Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x5QDRrGO031639; Wed, 26 Jun 2019 13:27:53 GMT MIME-Version: 1.0 Message-ID: <5423d87a-a55b-4362-8ae9-b5e25323fb49@default> Date: Wed, 26 Jun 2019 06:27:52 -0700 (PDT) From: Drew Adams To: =?iso-8859-1?B?S+l2aW4gTGUgR291Z3VlYw==?= , 35564@debbugs.gnu.org Subject: RE: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> In-Reply-To: <87h88cvpkj.fsf_-_@gmail.com> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4861.0 (x86)] Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9299 signatures=668687 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=881 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906260161 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9299 signatures=668687 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=948 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906260160 X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 35564 Cc: Stefan Monnier , Noam Postavsky X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Please do not hard-code any particular face. Ever. (add-face-text-property 0 (length prompt)=20 'minibuffer-prompt t prompt)) ^^^^^^^^^^^^^^^^^^ Yes, I know that the code this patch would replace already does that. But it shouldn't. Nothing is gained by imposing such things on users and making it hard for them to control such behavior as they wish. From debbugs-submit-bounces@debbugs.gnu.org Wed Jun 26 10:33:12 2019 Received: (at 35564) by debbugs.gnu.org; 26 Jun 2019 14:33:12 +0000 Received: from localhost ([127.0.0.1]:36671 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hg8z1-000773-Mk for submit@debbugs.gnu.org; Wed, 26 Jun 2019 10:33:11 -0400 Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:49056) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hg8yy-00076o-KZ for 35564@debbugs.gnu.org; Wed, 26 Jun 2019 10:33:09 -0400 Received: from pmg2.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id 0B4F18116F; Wed, 26 Jun 2019 10:33:03 -0400 (EDT) Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id AE9EE8030C; Wed, 26 Jun 2019 10:33:01 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1561559581; bh=VQbDHxafwJLHY580z5m3tNFLHlf2mOLflMoQX1s3cKE=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=Z2LGVnlL8Jr3RG79PjgnJUL4/O4lo224DA6gpy+twpHWLMeyIN/5/jNdKRZptOcQ7 yER8BLW7MC+R9urQ6xCsS+uPdZk1hgGJnkHED71Zp8STuT98C5TXHM5Uqg3W2uwao+ jW8TtAxLhNq1SepUTaLISSAB+FEIUoNa1KZYoWU3dhB+1qE5Ry4hNoEGz0vjA6YHXX cPf8GEFEJyO670STT4uGTGHH7HQez5PEB7hPi8F6yVav2ZOqwdjXbSVP6gCxVWMIhI Bjz5LgY6JgTr0Cmdit/Bh163O/X2My7/42wvSeeXCMywGpDBSmfNEevZxemj7GghY5 9G49befgQpK5A== Received: from pastel (76-10-151-214.dsl.teksavvy.com [76.10.151.214]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 7E5B31204BB; Wed, 26 Jun 2019 10:33:01 -0400 (EDT) From: Stefan Monnier To: =?windows-1252?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters Message-ID: References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> Date: Wed, 26 Jun 2019 10:33:00 -0400 In-Reply-To: <87h88cvpkj.fsf_-_@gmail.com> (=?windows-1252?Q?=22K=E9vin?= Le Gouguec"'s message of "Wed, 26 Jun 2019 08:16:44 +0200") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-SPAM-INFO: Spam detection results: 0 ALL_TRUSTED -1 Passed through trusted hosts only via SMTP BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain X-SPAM-LEVEL: X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Noam Postavsky X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) I wouldn't bother with the read--propertize-prompt auxiliary function, but ... LGTM (including the use of a hardcoded face ;-) Stefan K=C3=A9vin Le Gouguec writes: > And here is the third set of patches. > > > > > The first patch is unchanged (it adjusts y-or-n-p so that the prompt's > text properties are preserved), the second patch uses the new > (literal=C2=A0=E2=80=A6) feature from rx and adds a test case for > dired--isolated-char-p[1]. > > Quoting my previous email: > >> Some things I wonder about: >>=20 >> 1. About read--propertize-prompt=E2=80=A6 >>=20 >> 1. Should the function return a copy of its argument instead of >> propertizing it directly? >>=20 >> 2. Is it properly named? Does it fit in subr.el? I placed it there >> because I figured other users of read-char in subr.el could use >> it, e.g. read-char-choice. >>=20 >> 2. dired-aux.el already contains some logic to detect isolated >> characters; I could not think of a way to re-use it, so I added my >> own functions to find *non*-isolated characters. I added unit tests >> for these new functions; still, there may be some redundancy there. > > Thank you for your time. > > > [1] (should-not (dired--isolated-char-p "foo `bar`?" 9)) From debbugs-submit-bounces@debbugs.gnu.org Thu Jun 27 01:58:17 2019 Received: (at 35564) by debbugs.gnu.org; 27 Jun 2019 05:58:17 +0000 Received: from localhost ([127.0.0.1]:37297 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgNQG-00085Z-Qw for submit@debbugs.gnu.org; Thu, 27 Jun 2019 01:58:17 -0400 Received: from mail-wm1-f66.google.com ([209.85.128.66]:50547) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgNQE-00085M-4Q for 35564@debbugs.gnu.org; Thu, 27 Jun 2019 01:58:14 -0400 Received: by mail-wm1-f66.google.com with SMTP id c66so4384259wmf.0 for <35564@debbugs.gnu.org>; Wed, 26 Jun 2019 22:58:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=KTLSDwivz0EOGDSp9Q0pv3Aty7h6UIYw51FSd0ebM6Q=; b=AEHTCUxesB7CS+aO2B0NKEktfKyO5u1Fy1jf+YErg6V8TmKnroIvcnKqduOdM+nyFz CluRcvqSWsDUdggEutJAkl34+0Rt0FRNi9h9zE2C6TjVMk5/B0mg0+HekYO8y6cVbULv hUZrrglubVhTGD88188GD+otAJ+Cxx14r66vDrFyuOnmW0zMUHm2e02Bv7DQXrxdvCOQ hDEAxMBj15yuOU7unK3v94xt8g4L//5ZjPc/0kAwomxwe0ws+316b/RFnQOFvuN4xtTV I+3hlBrzdZezCCTkkLJPx5sRU8X5joPz2BdxN4BL9U+JLy/uzQGIHkJW1ICOxSHEYLej XZdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=KTLSDwivz0EOGDSp9Q0pv3Aty7h6UIYw51FSd0ebM6Q=; b=Z1x+uymayY9J8NmgQSKdyRFcKQlI5DErdtAgs2IC5hXt+PioNchFRRMSS47QUMuyr8 k3feW8jqA3Ms9Z5Hf6yIxO8TPI08UiCX3RYTbHR391p+wEY2wCRUAijwzJHa9JMl3bF0 wJLG1OY+07Y4O52truUOv4y79pFqC8yaUx1qhbW9ZSNLQzIk0Ocv3513TpDsXhumPi4b PQWb2lH6cAuw9xDIGhcJccPRDvEyIBkGq5LctiqIkvzaX/Z99cf0GNbi8Aqm1n9oTqBs 4516H1QcTI/3S0pDKLnaQr/epr6owXGUo6wd3NArGTngQYotJwC4AY8fXNa0L1lBfCIC ORqw== X-Gm-Message-State: APjAAAWgq+EkiaOA3z7u/ppJz/biwlTUaghBSMoS/RJ2FRqYBNiLC/R2 FLtZ4yAwdKYaU2CSLqz0SSY= X-Google-Smtp-Source: APXvYqxnrNUi/qtdSJovQYDN72TNJ+rszOSKF3TnifaTkc9qd6tq4NGOwS7XApLjgisPvSYsStDHlA== X-Received: by 2002:a1c:df46:: with SMTP id w67mr1656489wmg.69.1561615088024; Wed, 26 Jun 2019 22:58:08 -0700 (PDT) Received: from my-little-tumbleweed (71.142.13.109.rev.sfr.net. [109.13.142.71]) by smtp.gmail.com with ESMTPSA id z126sm5979547wmb.32.2019.06.26.22.58.06 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 26 Jun 2019 22:58:07 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Drew Adams Subject: Re: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <5423d87a-a55b-4362-8ae9-b5e25323fb49@default> Date: Thu, 27 Jun 2019 07:58:06 +0200 In-Reply-To: <5423d87a-a55b-4362-8ae9-b5e25323fb49@default> (Drew Adams's message of "Wed, 26 Jun 2019 06:27:52 -0700 (PDT)") Message-ID: <87ftnvr2mp.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Stefan Monnier , Noam Postavsky X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Drew Adams writes: > Please do not hard-code any particular face. Ever. > > (add-face-text-property 0 (length prompt) > 'minibuffer-prompt t prompt)) > ^^^^^^^^^^^^^^^^^^ > > Yes, I know that the code this patch would replace > already does that. But it shouldn't. > > Nothing is gained by imposing such things on users > and making it hard for them to control such behavior > as they wish. While I am not entirely satisfied with the resolution of the previous discussion on emacs-devel[1] (mostly because this thread arguably lacks a resolution[2]), I'd like to cross this bug (i.e. Dired's brain-tripping warning) off my list before tackling the more general issue of read-* functions abusing the minibuffer-prompt face. [1] https://lists.gnu.org/archive/html/emacs-devel/2019-05/msg00340.html [2] https://lists.gnu.org/archive/html/emacs-devel/2019-05/msg00344.html From debbugs-submit-bounces@debbugs.gnu.org Thu Jun 27 02:15:35 2019 Received: (at 35564) by debbugs.gnu.org; 27 Jun 2019 06:15:35 +0000 Received: from localhost ([127.0.0.1]:37304 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgNh1-0008Us-CH for submit@debbugs.gnu.org; Thu, 27 Jun 2019 02:15:35 -0400 Received: from mail-wm1-f50.google.com ([209.85.128.50]:54096) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgNgz-0008Ug-Vk for 35564@debbugs.gnu.org; Thu, 27 Jun 2019 02:15:34 -0400 Received: by mail-wm1-f50.google.com with SMTP id x15so4423318wmj.3 for <35564@debbugs.gnu.org>; Wed, 26 Jun 2019 23:15:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=FkJSyz5XA3dqWVgYfxPjlM7F6alJBfv03SvIhs84BsM=; b=F3i1B0LeDdGSW2n2IzVdLnTA3LvL+K17Cze0RZ4DE/XtiwvDFGg40ORDiu+DW/BQJ7 BgAM/GpMFouNF6KXJhhb+YGx13pI56D+gjiN6luCVV53F6g/9lzcWTOU3XKe0BLbduF+ DIzGEhNkw/ZSqqN0CMks0D4it+ADd0AZ032R9FocfS4huDLUnjcUaJ54aqTtwRW1T96o PPEYKkKPdwKq2oz5nHfjLPnd0zI8w75I5d4mRIFJdS/fXSSer9ZBgmf7HCl3dpiHcguz bWwxDu0idwejAJs2zAvcoE5MxVPMFSDWXIFuF3Wxu6ELrIoI9TEblLxeH2Dnn+QSpWdK 3ZFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=FkJSyz5XA3dqWVgYfxPjlM7F6alJBfv03SvIhs84BsM=; b=eoT3pFa02lhjwKlyg5y+0548RUzhxbbdZw6dahFQso1hZQKLnHb5VTFJNn2RE9mtW0 FiVGwAODhSl7d5RJx7rRpTLbZjkqsgqO3TM1BRagXstjeOlWehlQpnxFNeE/8zFYPxW4 8mkGhZZ2dda+3FX7MNIjabzAsWGRyLXtBx6FtFTwerRwspU7ewVmHLhuqz75g7cV7zjG I3hs0ljGDJXa71s65ydEdmwTC5/gvUY94gY5jYGTW7HBktPBAIsgWpl3Ex3/xT4loj77 tZw1Nwg2gs/R/eMP18Ic8bZ2sYn/VAUMnxTG2P5BQsR8wznbvc4EdlJp2Gkj9KGOJnIF y0Vw== X-Gm-Message-State: APjAAAXmiWyKgf5DHY46VpI0vWyVZUhdEFOYwORf1sjlEEbfUTtaSISb M4SerVw3FWT1hkkM1cQDFXg= X-Google-Smtp-Source: APXvYqwQ3DZCCa/IDiKiDBhVy77C60VZJJfkVu/T8o/k/XaHDqwjMoRbMITDojYMJodfC2AE/01NTg== X-Received: by 2002:a1c:6154:: with SMTP id v81mr1769438wmb.92.1561616128193; Wed, 26 Jun 2019 23:15:28 -0700 (PDT) Received: from my-little-tumbleweed (71.142.13.109.rev.sfr.net. [109.13.142.71]) by smtp.gmail.com with ESMTPSA id 67sm5209272wmd.38.2019.06.26.23.15.27 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 26 Jun 2019 23:15:27 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Stefan Monnier Subject: Re: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> Date: Thu, 27 Jun 2019 08:15:25 +0200 In-Reply-To: (Stefan Monnier's message of "Wed, 26 Jun 2019 10:33:00 -0400") Message-ID: <87d0izr1tu.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Noam Postavsky X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Stefan Monnier writes: > I wouldn't bother with the read--propertize-prompt auxiliary > function, but ... LGTM Fair enough. I figured having a function would reduce the inertia of changing other prompts which are propertized rigidly, and make it easier to (maybe, someday) change the face that these prompts use in one go. Though it's probably better to wait for a few prompts to be adapted, deduce some pattern in the way they are propertized, and then introduce a new function to do the job. I'll submit a revised patch without the auxiliary function. From debbugs-submit-bounces@debbugs.gnu.org Thu Jun 27 19:31:45 2019 Received: (at 35564) by debbugs.gnu.org; 27 Jun 2019 23:31:45 +0000 Received: from localhost ([127.0.0.1]:40044 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgdrk-0004up-Hq for submit@debbugs.gnu.org; Thu, 27 Jun 2019 19:31:45 -0400 Received: from mail-io1-f48.google.com ([209.85.166.48]:41156) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgdri-0004uX-0m for 35564@debbugs.gnu.org; Thu, 27 Jun 2019 19:31:42 -0400 Received: by mail-io1-f48.google.com with SMTP id w25so8564150ioc.8 for <35564@debbugs.gnu.org>; Thu, 27 Jun 2019 16:31:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=Pv0cxXyHHBsyDSzRmrIYQ9v0qVxl5w9fg8tTwEvhy6s=; b=IrS+w9Czzba+0kTuNMJbMSTi8MnG83JSoA/Rui8rJWixkjdwFOWW61c3gnKHgq6I0H 0U9n5c5Yw34AflBfFDy3iX3jc2AZCwOcE2P37PlF6XfQDj6sy8TcZNqeyYlr613WfrVe +8Wm0LWo5I+WelFk8PBMfe4WCp4TPcI665DLatKI+93oksFpiturTU5Y9gw2WW4kVSOs cB9JtLoAzKi5OecO1+OyqQ/4wk3KCOiPAyC0iLZaHAVtAiRsejMPOO4tPI4q+wqZykqx N0LcpnABFSNcdJD2UACuZ0b31QSvn4Opdv++Ek3YR/GPesZFyVug0PqOLvjKRw98xRWB xd4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=Pv0cxXyHHBsyDSzRmrIYQ9v0qVxl5w9fg8tTwEvhy6s=; b=IzVN521C7Ps6DM53uqkhJUKum9Dne7avaN+c40g1DNGIRNwT/5U8LM5/uwuyp9UkbL oq7FFxX90Kqr9O1pjEjFjcSC8nWFil6auKgFkjpzjPknkMOE72jZnRgW2sGTB8qpjIEw Dm4wtK85AIne1GSK9xxl1ZfMDekba9qRxm8wq9JBNwLyRRauWpuJLR6ewO0mW9m/J7qv HlroxFz+bHW46OV/pZcn/JxjlcwokSvTpeMs+6TQM6U4c9b8yYNdIlLLLjmtX+qKnJJq WpFPfA3dUkkIsTYjwrCglpXPJOXSseXZ0Rn7XObLziDgkcRV03QL4VHFlwtiknK+n07o se0Q== X-Gm-Message-State: APjAAAUwewbPLlytnmBCt80PE6wLMhCYoFBqx2OqS0sJCmy3bfWUyjZg 4j8B7Nm3PgVNvT0Yi+5P5QY= X-Google-Smtp-Source: APXvYqx6V6UGh8CE5+kDkMKhOf8Op2AlflUCrhZwnADFWMHD+wn1LnHEhcxTdgCsVV5jvF/l8ddV8w== X-Received: by 2002:a6b:1604:: with SMTP id 4mr7161819iow.245.1561678296274; Thu, 27 Jun 2019 16:31:36 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id a7sm1008761iok.19.2019.06.27.16.31.34 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 27 Jun 2019 16:31:35 -0700 (PDT) From: Noam Postavsky To: =?utf-8?Q?K=C3=A9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> Date: Thu, 27 Jun 2019 19:31:34 -0400 In-Reply-To: <87h88cvpkj.fsf_-_@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Wed, 26 Jun 2019 08:16:44 +0200") Message-ID: <87a7e27gh5.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2.90 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable K=C3=A9vin Le Gouguec writes: >> 2. dired-aux.el already contains some logic to detect isolated >> characters Yes, this was kind of bugging me, so here's a patch to reuse that logic (it applies on top of yours). While doing this I noticed that we earlier missed that `*` is not considered isolated, unlike `?`. Assuming no problems, I'll just push your two patches followed by mine (I considered squashing, but probably that makes things harder to follow in this case). --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=0003-Dedup-dired-aux-isolated-char-searching.patch Content-Description: patch >From 52af7efc5e0c673b24e09991db275112212f3fbf Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 27 Jun 2019 19:15:56 -0400 Subject: [PATCH 3/3] Dedup dired-aux isolated char searching * lisp/dired-aux.el (dired-isolated-string-re): Use explicitly numbered groups. (dired--star-or-qmark-p): Add START parameter. Make sure to return the first isolated match. (dired--no-subst-prompt): Operate on a list of positions rather than searching again for isolated chars. (dired--isolated-char-p): Remove. (dired--need-confirm-positions): New function. (dired-do-shell-command): Use it. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p): Remove. (dired-test-highlight-metachar): Adjust to new functions. Make sure that `*` isn't considered isolated. --- lisp/dired-aux.el | 108 +++++++++++++++++++------------------------ test/lisp/dired-aux-tests.el | 31 ++++++------- 2 files changed, 62 insertions(+), 77 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 079e4f102f..e716b2b42c 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -60,60 +60,55 @@ (defun dired-isolated-string-re (string) of a string followed/prefixed with an space. The regexp capture the preceding blank, STRING and the following blank as the groups 1, 2 and 3 respectively." - (format "\\(\\`\\|[ \t]\\)\\(%s\\)\\([ \t]\\|\\'\\)" string)) + (format "\\(?1:\\`\\|[ \t]\\)\\(?2:%s\\)\\(?3:[ \t]\\|\\'\\)" string)) -(defun dired--star-or-qmark-p (string match &optional keep) +(defun dired--star-or-qmark-p (string match &optional keep start) "Return non-nil if STRING contains isolated MATCH or `\\=`?\\=`'. MATCH should be the strings \"?\", `\\=`?\\=`', \"*\" or nil. The latter means STRING contains either \"?\" or `\\=`?\\=`' or \"*\". If optional arg KEEP is non-nil, then preserve the match data. Otherwise, this function changes it and saves MATCH as the second match group. +START is the position to start matching from. Isolated means that MATCH is surrounded by spaces or at the beginning/end of STRING followed/prefixed with an space. A match to `\\=`?\\=`', isolated or not, is also valid." - (let ((regexps (list (dired-isolated-string-re (if match (regexp-quote match) "[*?]"))))) + (let ((regexp (dired-isolated-string-re (if match (regexp-quote match) "[*?]")))) (when (or (null match) (equal match "?")) - (setq regexps (append (list "\\(\\)\\(`\\?`\\)\\(\\)") regexps))) - (cl-some (lambda (x) - (funcall (if keep #'string-match-p #'string-match) x string)) - regexps))) - -(defun dired--isolated-char-p (command pos) - "Assert whether the character at POS is isolated within COMMAND. -A character is isolated if: -- it is surrounded by whitespace, the start of the command, or - the end of the command, -- it is surrounded by `\\=`' characters." - (let ((start (max 0 (1- pos))) - (char (string (aref command pos)))) - (and (string-match - (rx (or (seq (or bos blank) - (group-n 1 (literal char)) - (or eos blank)) - (seq ?` (group-n 1 (literal char)) ?`))) - command start) - (= pos (match-beginning 1))))) - -(defun dired--highlight-nosubst-char (command char) - "Highlight occurences of CHAR that are not isolated in COMMAND. -These occurences will not be substituted; they will be sent as-is -to the shell, which may interpret them as wildcards." - (save-match-data - (let ((highlighted (substring-no-properties command)) - (pos 0)) - (while (string-match (regexp-quote char) command pos) - (let ((start (match-beginning 0)) - (end (match-end 0))) - (unless (dired--isolated-char-p command start) - (add-face-text-property start end 'warning nil highlighted)) - (setq pos end))) - highlighted))) - -(defun dired--no-subst-prompt (command char) - (let ((highlighted-command (dired--highlight-nosubst-char command char)) - (prompt "Confirm--the highlighted characters will not be substituted:")) - (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + (cl-callf concat regexp "\\|\\(?1:\\)\\(?2:`\\?`\\)\\(?3:\\)")) + (funcall (if keep #'string-match-p #'string-match) regexp string start))) + +(defun dired--need-confirm-positions (command string) + "Search for non-isolated matches of STRING in COMMAND. +Return a list of positions that match STRING, but would not be +considered \"isolated\" by `dired--star-or-qmark-p'." + (cl-assert (= (length string) 1)) + (let ((start 0) + (isolated-char-positions nil) + (confirm-positions nil) + (regexp (regexp-quote string))) + ;; Collect all ? and * surrounded by spaces and `?`. + (while (dired--star-or-qmark-p command string nil start) + (push (cons (match-beginning 2) (match-end 2)) + isolated-char-positions) + (setq start (match-end 2))) + ;; Now collect any remaining ? and *. + (setq start 0) + (while (string-match regexp command start) + (unless (cl-member (match-beginning 0) isolated-char-positions + :test (lambda (pos match) + (<= (car match) pos (cdr match)))) + (push (match-beginning 0) confirm-positions)) + (setq start (match-end 0))) + confirm-positions)) + +(defun dired--no-subst-prompt (command char-positions) + (let ((highlighted (substring-no-properties command))) + (dolist (pos char-positions) + (add-face-text-property pos (1+ pos) 'warning nil highlighted)) + (format-message "\ +Confirm--the highlighted characters will not be substituted:\n%s +Proceed?" highlighted))) ;;;###autoload (defun dired-diff (file &optional switches) @@ -779,26 +774,19 @@ (defun dired-do-shell-command (command &optional arg file-list) (dired-read-shell-command "! on %s: " current-prefix-arg files) current-prefix-arg files))) - (cl-flet ((need-confirm-p - (cmd str) - (let ((res cmd) - (regexp (regexp-quote str))) - ;; Drop all ? and * surrounded by spaces and `?`. - (while (and (string-match regexp res) - (dired--star-or-qmark-p res str)) - (setq res (replace-match "" t t res 2))) - (string-match regexp res)))) (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) + (confirmations nil) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. - (ok (cond ((not (or on-each no-subst)) - (error "You can not combine `*' and `?' substitution marks")) - ((need-confirm-p command "*") - (y-or-n-p (dired--no-subst-prompt command "*"))) - ((need-confirm-p command "?") - (y-or-n-p (dired--no-subst-prompt command "?"))) - (t)))) + (ok (cond + ((not (or on-each no-subst)) + (error "You can not combine `*' and `?' substitution marks")) + ((setq confirmations (dired--need-confirm-positions command "*")) + (y-or-n-p (dired--no-subst-prompt confirmations command))) + ((setq confirmations (dired--need-confirm-positions command "?")) + (y-or-n-p (dired--no-subst-prompt command confirmations))) + (t)))) (cond ((not ok) (message "Command canceled")) (t (if on-each @@ -809,7 +797,7 @@ (defun dired-do-shell-command (command &optional arg file-list) nil file-list) ;; execute the shell command (dired-run-shell-command - (dired-shell-stuff-it command file-list nil arg)))))))) + (dired-shell-stuff-it command file-list nil arg))))))) ;; Might use {,} for bash or csh: (defvar dired-mark-prefix "" diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 80b6393931..3f4bfffaf6 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,34 +114,31 @@ (ert-deftest dired-test-bug30624 () (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) -(ert-deftest dired-test-isolated-char-p () - (should (dired--isolated-char-p "?" 0)) - (should (dired--isolated-char-p "? " 0)) - (should (dired--isolated-char-p " ?" 1)) - (should (dired--isolated-char-p " ? " 1)) - (should (dired--isolated-char-p "foo bar ? baz" 8)) - (should (dired--isolated-char-p "foo -i`?`" 7)) - (should-not (dired--isolated-char-p "foo `bar`?" 9)) - (should-not (dired--isolated-char-p "foo 'bar?'" 8)) - (should-not (dired--isolated-char-p "foo bar?baz" 7)) - (should-not (dired--isolated-char-p "foo bar?" 7))) - (ert-deftest dired-test-highlight-metachar () "Check that non-isolated meta-characters are highlighted" (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") - (result (dired--highlight-nosubst-char command "?"))) + (prompt (dired--no-subst-prompt + command + (dired--need-confirm-positions command "?"))) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 14 'face nil result)) (should (equal 'warning (get-text-property 15 'face result))) (should-not (text-property-not-all 16 28 'face nil result)) (should (equal 'warning (get-text-property 29 'face result))) (should-not (text-property-not-all 30 39 'face nil result))) - (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") - (result (dired--highlight-nosubst-char command "*"))) + ;; Note that `?` is considered isolated, but `*` is not. + (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (prompt (dired--no-subst-prompt + command + (dired--need-confirm-positions command "*"))) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 10 'face nil result)) (should (equal 'warning (get-text-property 11 'face result))) (should-not (text-property-not-all 12 23 'face nil result)) - (should (equal 'warning (get-text-property 24 'face result))) - (should-not (text-property-not-all 25 29 'face nil result)))) + (should (equal 'warning (get-text-property 25 'face result))) + (should-not (text-property-not-all 26 32 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.11.0 --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 28 02:15:56 2019 Received: (at 35564) by debbugs.gnu.org; 28 Jun 2019 06:15:56 +0000 Received: from localhost ([127.0.0.1]:40252 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgkAu-0002tc-0A for submit@debbugs.gnu.org; Fri, 28 Jun 2019 02:15:56 -0400 Received: from mail-wr1-f42.google.com ([209.85.221.42]:44661) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgkAq-0002tN-2b for 35564@debbugs.gnu.org; Fri, 28 Jun 2019 02:15:52 -0400 Received: by mail-wr1-f42.google.com with SMTP id r16so3068621wrl.11 for <35564@debbugs.gnu.org>; Thu, 27 Jun 2019 23:15:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=xe2m+v0xUg9Eo1v92utAIaHQGmR/rlIBcKJ75jq4k0w=; b=VrMuuE6mTLpS0/JRTVtRp4xOZWUIBttgoJ9IS2cfvwp7VkzDL1aTtGUf0pzwshuV8X 0cDZWDurwalh7c8FGiJnNSuhksHY2jMJhFXioIIHAuTosX6mDbpP2oc8yiJnCz6OiS1z kOlMR8J116mxH0dSVulQHoQ5oLUHQpU0QPx4iozzfH2R3slbt2gwvh20wELI2twDWhJ+ UqLAvY7CKiToherXJtM6k+NIVVsQ30Fkjg+bzTY2/TRLHTIBRsY4mcdFNBxeEreGkIWY ceRv89DWBBQXFG8C1PqCwrSWC5Wj0xj2mZ54qw92yZB6VxWiU8DwoT4/chfqPNjNnGSF UyCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=xe2m+v0xUg9Eo1v92utAIaHQGmR/rlIBcKJ75jq4k0w=; b=hklLw2PQPpl4gc6P2chf16wVPyvySaSrT2ljZbW8w7+gPyC18dhaBKLQk80Bn3QP2A 8XUcs+37EUsXlkexMlCOjD+u4+idUiEqDwSVYJ5r0AmpiO9IQC45FLqFfnLJAvQ6dotx Gg9Le71Wdxn+Klc/eXpkK6yzrlHfev6Pkwhxk+xMZFJRDRINQxfP/XXK43gcHT+KzmKD +rb3pTyjCQIbei/392qNxBHwLwewZB7IdG+p8E+Hmnul0KYmUaBFD3aKsuJoTnK2sZm8 r9ZtANk+N9kAvBJ82V+dYtfel8XleFE/qkWzOFc+lP7pulb4EI/xC/fjtYRgbSO9PHV5 vYNQ== X-Gm-Message-State: APjAAAX3l28al2O5Ille2sXD3tPHAWRNdybGpDoJJdV9z18PjGOxnZAU /sFkAKJRyCDkTmtiflA10Fs= X-Google-Smtp-Source: APXvYqxpCRICAfwFiMlyUqrUploMTLkI1uTBOCDL0keqOayQu5teSC7Xf+I/y58zKWyL9I7KItTwnw== X-Received: by 2002:adf:f98b:: with SMTP id f11mr545257wrr.231.1561702546295; Thu, 27 Jun 2019 23:15:46 -0700 (PDT) Received: from my-little-tumbleweed (71.142.13.109.rev.sfr.net. [109.13.142.71]) by smtp.gmail.com with ESMTPSA id o4sm1046553wmh.35.2019.06.27.23.15.44 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Thu, 27 Jun 2019 23:15:45 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Noam Postavsky Subject: Re: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87a7e27gh5.fsf@gmail.com> Date: Fri, 28 Jun 2019 08:15:44 +0200 In-Reply-To: <87a7e27gh5.fsf@gmail.com> (Noam Postavsky's message of "Thu, 27 Jun 2019 19:31:34 -0400") Message-ID: <8736jujkvj.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Noam Postavsky writes: > Yes, this was kind of bugging me, so here's a patch to reuse that logic > (it applies on top of yours). While doing this I noticed that we > earlier missed that `*` is not considered isolated, unlike `?`. Thank you very much! > Assuming no problems, I'll just push your two patches followed by mine Fine by me, although it just occurs to me that I forgot to mention the bug number in my commit messages. Here are updated patches: --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Preserve-text-properties-in-y-or-n-p-prompts.patch >From f34a6271f86e2f6045fc8e37c157676e046f85a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:03:59 +0200 Subject: [PATCH 1/2] Preserve text properties in y-or-n-p prompts * lisp/subr.el (read--propertize-prompt): New function to append the prompt face to a string. (y-or-n-p): Use it instead of discarding potential text properties. (Bug#35564) --- lisp/subr.el | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lisp/subr.el b/lisp/subr.el index baff1e909a..67c4f1da3a 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2334,6 +2334,9 @@ memory-limit ;;;; Input and display facilities. +(defun read--propertize-prompt (prompt) + (add-face-text-property 0 (length prompt) 'minibuffer-prompt t prompt)) + (defconst read-key-empty-map (make-sparse-keymap)) (defvar read-key-delay 0.01) ;Fast enough for 100Hz repeat rate, hopefully. @@ -2671,14 +2674,14 @@ y-or-n-p (let* ((scroll-actions '(recenter scroll-up scroll-down scroll-other-window scroll-other-window-down)) (key - (let ((cursor-in-echo-area t)) + (let ((cursor-in-echo-area t) + (prompt (if (memq answer scroll-actions) + prompt + (concat "Please answer y or n. " prompt)))) (when minibuffer-auto-raise (raise-frame (window-frame (minibuffer-window)))) - (read-key (propertize (if (memq answer scroll-actions) - prompt - (concat "Please answer y or n. " - prompt)) - 'face 'minibuffer-prompt))))) + (read--propertize-prompt prompt) + (read-key prompt)))) (setq answer (lookup-key query-replace-map (vector key) t)) (cond ((memq answer '(skip act)) nil) -- 2.21.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-Tweak-dired-warning-about-wildcard-characters.patch >From a70bbeae31315a3c1b8baf979e27be3dbc4f7eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:19:44 +0200 Subject: [PATCH 2/2] Tweak dired warning about "wildcard" characters Non-isolated '?' and '*' characters may be quoted, or backslash-escaped; we do not know for a fact that the shell will interpret them as wildcards. Rephrase the prompt and highlight the characters so that the user sees exactly what we are talking about. * lisp/dired-aux.el (dired--isolated-char-p) (dired--highlight-nosubst-char, dired--no-subst-prompt): New functions. (dired-do-shell-command): Use them. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p) (dired-test-highlight-metachar): Test the new functions. (Bug#35564) --- lisp/dired-aux.el | 42 ++++++++++++++++++++++++++++++++---- test/lisp/dired-aux-tests.el | 28 ++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 5e4ec4d1ec..079e4f102f 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -79,6 +79,42 @@ dired--star-or-qmark-p (funcall (if keep #'string-match-p #'string-match) x string)) regexps))) +(defun dired--isolated-char-p (command pos) + "Assert whether the character at POS is isolated within COMMAND. +A character is isolated if: +- it is surrounded by whitespace, the start of the command, or + the end of the command, +- it is surrounded by `\\=`' characters." + (let ((start (max 0 (1- pos))) + (char (string (aref command pos)))) + (and (string-match + (rx (or (seq (or bos blank) + (group-n 1 (literal char)) + (or eos blank)) + (seq ?` (group-n 1 (literal char)) ?`))) + command start) + (= pos (match-beginning 1))))) + +(defun dired--highlight-nosubst-char (command char) + "Highlight occurences of CHAR that are not isolated in COMMAND. +These occurences will not be substituted; they will be sent as-is +to the shell, which may interpret them as wildcards." + (save-match-data + (let ((highlighted (substring-no-properties command)) + (pos 0)) + (while (string-match (regexp-quote char) command pos) + (let ((start (match-beginning 0)) + (end (match-end 0))) + (unless (dired--isolated-char-p command start) + (add-face-text-property start end 'warning nil highlighted)) + (setq pos end))) + highlighted))) + +(defun dired--no-subst-prompt (command char) + (let ((highlighted-command (dired--highlight-nosubst-char command char)) + (prompt "Confirm--the highlighted characters will not be substituted:")) + (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + ;;;###autoload (defun dired-diff (file &optional switches) "Compare file at point with FILE using `diff'. @@ -759,11 +795,9 @@ dired-do-shell-command (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((need-confirm-p command "*") - (y-or-n-p (format-message - "Confirm--do you mean to use `*' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "*"))) ((need-confirm-p command "?") - (y-or-n-p (format-message - "Confirm--do you mean to use `?' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "?"))) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ccd3192792..80b6393931 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,6 +114,34 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(ert-deftest dired-test-isolated-char-p () + (should (dired--isolated-char-p "?" 0)) + (should (dired--isolated-char-p "? " 0)) + (should (dired--isolated-char-p " ?" 1)) + (should (dired--isolated-char-p " ? " 1)) + (should (dired--isolated-char-p "foo bar ? baz" 8)) + (should (dired--isolated-char-p "foo -i`?`" 7)) + (should-not (dired--isolated-char-p "foo `bar`?" 9)) + (should-not (dired--isolated-char-p "foo 'bar?'" 8)) + (should-not (dired--isolated-char-p "foo bar?baz" 7)) + (should-not (dired--isolated-char-p "foo bar?" 7))) + +(ert-deftest dired-test-highlight-metachar () + "Check that non-isolated meta-characters are highlighted" + (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (result (dired--highlight-nosubst-char command "?"))) + (should-not (text-property-not-all 1 14 'face nil result)) + (should (equal 'warning (get-text-property 15 'face result))) + (should-not (text-property-not-all 16 28 'face nil result)) + (should (equal 'warning (get-text-property 29 'face result))) + (should-not (text-property-not-all 30 39 'face nil result))) + (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") + (result (dired--highlight-nosubst-char command "*"))) + (should-not (text-property-not-all 1 10 'face nil result)) + (should (equal 'warning (get-text-property 11 'face result))) + (should-not (text-property-not-all 12 23 'face nil result)) + (should (equal 'warning (get-text-property 24 'face result))) + (should-not (text-property-not-all 25 29 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.21.0 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable > +(defun dired--no-subst-prompt (command char-positions) > [=E2=80=A6] > + ((setq confirmations (dired--need-confirm-positions comman= d "*")) > + (y-or-n-p (dired--no-subst-prompt confirmations command))) > + ((setq confirmations (dired--need-confirm-positions comman= d "?")) > + (y-or-n-p (dired--no-subst-prompt command confirmations))) Mmmm, am I missing something, or have the arguments to dired--no-subst-prompt been reversed in the "*" case? I.e. shoudn't > + (y-or-n-p (dired--no-subst-prompt confirmations command))) rather be > + (y-or-n-p (dired--no-subst-prompt command confirmations))) ? As things stand, "! grep 'foo.*'" in Dired fails, saying: let: Wrong type argument: stringp, (9) --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 28 11:35:54 2019 Received: (at 35564) by debbugs.gnu.org; 28 Jun 2019 15:35:54 +0000 Received: from localhost ([127.0.0.1]:42825 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgsuo-0002hf-9k for submit@debbugs.gnu.org; Fri, 28 Jun 2019 11:35:54 -0400 Received: from userp2130.oracle.com ([156.151.31.86]:35356) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgsul-0002hR-Lt for 35564@debbugs.gnu.org; Fri, 28 Jun 2019 11:35:52 -0400 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5SFXgSt166631; Fri, 28 Jun 2019 15:35:45 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=tGN6d7pdU4B29X2A4DaQVWBgy6KbHSrWYCp4xdSoAqg=; b=rc0OL4sJffUlro7hvLQkys6iPRB9KXDeZX/f1/0OiRlqjdkdrhUqZ5Ro8I5O/fyWUTES sBYwHHclumIW2kNgBdM13Fd1MJStw90w9CsS9SRnkgcLrMn5vfEOB5DUSlzt0aekGUlt xMd9bn69GxiN+yMCETxWlp3pn/2EqmyCox5T2VVM43Gvkyhy3/RltWP+ehiUvBK16Ayr i0CYDouJNHkg1TrVBrVyLLh4LEiX8UnZybebGu9A5WWXAJ5H2nUFhkqYsnGamqf4EPPw w56mIryfjxAOl9ZOssl0uTcbS6dzWtTswBe3e6sv8bvycxFO9UY/Tx4r/VLk3PNbPrG6 Vg== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by userp2130.oracle.com with ESMTP id 2t9brtpbw1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 28 Jun 2019 15:35:45 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5SFYrd6112655; Fri, 28 Jun 2019 15:35:44 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserp3020.oracle.com with ESMTP id 2t9p6vyhpb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 28 Jun 2019 15:35:44 +0000 Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x5SFZf6b014162; Fri, 28 Jun 2019 15:35:41 GMT MIME-Version: 1.0 Message-ID: <32acf7a4-70d2-4c33-a3f5-18b082903d4a@default> Date: Fri, 28 Jun 2019 08:35:41 -0700 (PDT) From: Drew Adams To: =?iso-8859-1?B?S+l2aW4gTGUgR291Z3VlYw==?= , Noam Postavsky Subject: RE: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87a7e27gh5.fsf@gmail.com> <8736jujkvj.fsf@gmail.com> In-Reply-To: <8736jujkvj.fsf@gmail.com> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4861.0 (x86)] Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9302 signatures=668688 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906280179 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9302 signatures=668688 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906280180 X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) (Apologies if I missed something - I took only a quick look at the patches and the bug report.) The old question=20 "Confirm--do you mean to use `*' as a wildcard? " Seemed clear enough, I thought. But I see now from the bug report that it could be confusing. But the new question (and actually it's not even a question - it should be, no?) seems even less clear to me: "Confirm--the highlighted characters will not be substituted:" (And too long - "highlighted chars won't be substituted" says the same thing as "the highlighted...".) Maybe something like this? "Should highlighted chars be substituted? " or "Substitute highlighted occurrences of `*'? " But see next - 1. It's not clear to me what someone will understand by "substituted" here. What would (otherwise) be substituted for what, where, and for what purpose? What substitution are we talking about, and how would a user be expected to know what we mean, here? 2. Are there multiple different "characterS" involved, or is the confirmation about only _one_ character, in (possibly) multiple locations - occurrences of one char? 3. Is it the case that the new prompt does not, itself, show the character? Do you have to look elsewhere to see which char or chars(?) are meant by the prompt? Shouldn't the prompt itself show the char? I think more thought might need to be put into this, by those who understand what the code actually does, ways in which the resulting behavior could be confusing, and just what it is we're asking the user to confirm. (I'm not one who really understands all of this. I'm just saying that my guess is that things are still not so clear after the patching.) A final comment, which I'm not sure is relevant: We should not, in any case, _rely_ on any highlighting to get across meaning (semantics). Highlighting should always be an extra - a nice-to-have. Some users will not see the highlighting - it cannot be the only thing that gets the intended meaning across. (Again, I'm not saying that we _are_ relying on highlighting this way. I just want to be sure we're not. We don't want to unnecessarily introduce an accessibility problem.) From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 28 13:58:32 2019 Received: (at 35564) by debbugs.gnu.org; 28 Jun 2019 17:58:32 +0000 Received: from localhost ([127.0.0.1]:42938 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgv8p-0000AV-IS for submit@debbugs.gnu.org; Fri, 28 Jun 2019 13:58:32 -0400 Received: from mail-wr1-f52.google.com ([209.85.221.52]:40295) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgv8l-0000AD-1u for 35564@debbugs.gnu.org; Fri, 28 Jun 2019 13:58:27 -0400 Received: by mail-wr1-f52.google.com with SMTP id p11so7169447wre.7 for <35564@debbugs.gnu.org>; Fri, 28 Jun 2019 10:58:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=cUKy8CSmOqntMpgq7coaifqfpQgJj01Mk8TSfthjAe0=; b=udXtDXtSsxx9Jf5xV1GNWV3kGKp3P9amKU/jS6gtjKU77pQgekbObV0mUXu1lsEJ4b 9KhG27jVMmYU8CjA1URMMOd7dcZ2Mlt6Zgp/qhsIDMow4azLwsUYvhUL4Ks8Ike/Kz20 Mv827qVovodLBJAOPl0hdQsALpNnp+982dx1Ow+bRxppSynG2k9LU9uqtR/BHs9hB3od VzwsMi/0qiJZSPTWInB/0kis1mbc5VTjlSNuwueo3Ucjwu5sd/Kmfjr9y5gRaZXXAH7b sYSuRejhkWkDVzJ6bxQPkuSUjLxJbE6QqYzXEEPcnomtAU3NMmzpIWN+tmKyYRrNxMXX rJUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=cUKy8CSmOqntMpgq7coaifqfpQgJj01Mk8TSfthjAe0=; b=JHMG0/fYM7Fpfs5oxym66nc3NKiDmfjtdKsJCqK/9U9Y4mXVS4oN9aadaz+bn6M+gV Vcpk+kVcgWPW/zWaiUX5kt8/4UbXz13RK60x6mTjSNm0oP05OoeCVsy/wniNiymyXwEb /8y+fw7SeiZePJjsQz/dX8R73vpmh3uIraUXVg7xUUubHQe/tbjc5+J+RNbkb9Z0ewZ0 VuGzsYfAoJUwuq0872YtmMnaXJ/t1ZbRHCNwWpV3XGRwZa9dUGkbXyCDkKGbSRlmv8sY kWawB4y8fOKZ9guQob1bHUqHT9wbLd1G56gGZ2GgkcQc6Wv51S2hK1WV7cdEXeFT9dwx enbQ== X-Gm-Message-State: APjAAAXOU5FwJrK25VgnVBYDRbdzq6Oh7vQHnU02V05Z449i+4CQ0KFh GCih6PzQfgoFiIbneQiP5tE= X-Google-Smtp-Source: APXvYqxW+9DFN/JKDkuzrJMRpPJjfeHAbBWkF/KBPkEjiEQ/39dHe4OX38tgG7EzjozuEhd4J0GScw== X-Received: by 2002:adf:ed41:: with SMTP id u1mr8322716wro.162.1561744700957; Fri, 28 Jun 2019 10:58:20 -0700 (PDT) Received: from nc10-laptop ([109.190.253.14]) by smtp.gmail.com with ESMTPSA id j189sm3204666wmb.48.2019.06.28.10.58.17 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 28 Jun 2019 10:58:19 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Drew Adams Subject: Re: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87a7e27gh5.fsf@gmail.com> <8736jujkvj.fsf@gmail.com> <32acf7a4-70d2-4c33-a3f5-18b082903d4a@default> Date: Fri, 28 Jun 2019 19:58:13 +0200 In-Reply-To: <32acf7a4-70d2-4c33-a3f5-18b082903d4a@default> (Drew Adams's message of "Fri, 28 Jun 2019 08:35:41 -0700 (PDT)") Message-ID: <87ef3dvbgq.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Drew Adams writes: > But the new question (and actually it's not even a > question - it should be, no?) seems even less clear > to me: A question would probably make the interaction more fluid, I agree. As fun as messing with text properties has been, I would still very much favour a simpler solution in the form of a better question (where "better" mostly means "does not talk about wildcards"). As I mentioned, the only reason I came up with these highlighting shenanigans is because I could not come up with a better phrasing. Point taken about the new phrasing possibly being less clear; I was aiming for some sort of "is the following statement correct? yes/no" interaction. > (And too long - "highlighted chars won't be substituted" > says the same thing as "the highlighted...".) (Silly question: is it kosher to use contractions such as "won't" in user-facing text? Or were you pointing out the superfluous "the" and/or suggesting "chars" rather than "characters"?) > "Should highlighted chars be substituted? " > > or > > "Substitute highlighted occurrences of `*'? " Mmm; currently this prompt is raised when the code detects that the characters will *not* be substituted; answering "yes" makes Dired go on with the command, answering "no" aborts. If we phrased the question like you suggest, we should probably change the code to actually perform the substitutions should the user answer "yes". > 1. It's not clear to me what someone will understand > by "substituted" here. What would (otherwise) be > substituted for what, where, and for what purpose? > What substitution are we talking about, and how > would a user be expected to know what we mean, here? Right. Not sure how to make things clearer without quoting dired-do-shell-command's documentation, which would make the prompt quite verbose. > 2. Are there multiple different "characterS" involved, > or is the confirmation about only _one_ character, > in (possibly) multiple locations - occurrences of > one char? One character in (possibly) multiple locations. > 3. Is it the case that the new prompt does not, itself, > show the character? Do you have to look elsewhere > to see which char or chars(?) are meant by the > prompt? Shouldn't the prompt itself show the char? It does; the prompt shows the full command, and applies the warning face to the character(s). > A final comment, which I'm not sure is relevant: > > We should not, in any case, _rely_ on any > highlighting to get across meaning (semantics). > Highlighting should always be an extra - a > nice-to-have. Some users will not see the > highlighting - it cannot be the only thing that > gets the intended meaning across. > > (Again, I'm not saying that we _are_ relying on > highlighting this way. I just want to be sure > we're not. We don't want to unnecessarily > introduce an accessibility problem.) With the current patches, we absolutely totally completely _would_ rely on highlighting to get across semantics. Thank you for spelling it out as an accessibility problem; that kind of confirms my nagging feeling that the highlighting method has an unfavorable benefit/cost ratio (IOW, it's cute, but it might make things worse for some users). So to conclude, these are the paths forward that I see: (0. Drop the issue and grit my teeth when the warning shows up.) 1. find a simple rephrasing, 2. keep trying to make a more elaborate prompt, only using some other tricks to point out the characters. Example of path 1: > Confirm--do you mean to send `*' verbatim to the shell? (I don't like this one because it sounds like "do you want us to quote `*' to make sure the shell does not expand it?") Example of path 2: > Confirm--do you mean to send these characters as-is to the shell? > sed -e 's/foo?/foo!/' -e 's/bar?/bar!' > ^ ^ (I.e. using '^' to denote the non-isolated characters; not sure how clear it is that "these" refers to "the caracters underlined by a '^'") From debbugs-submit-bounces@debbugs.gnu.org Fri Jun 28 14:44:09 2019 Received: (at 35564) by debbugs.gnu.org; 28 Jun 2019 18:44:09 +0000 Received: from localhost ([127.0.0.1]:42977 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgvqy-0003hO-Hs for submit@debbugs.gnu.org; Fri, 28 Jun 2019 14:44:09 -0400 Received: from userp2130.oracle.com ([156.151.31.86]:35932) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hgvqv-0003gj-P7 for 35564@debbugs.gnu.org; Fri, 28 Jun 2019 14:44:06 -0400 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5SIdgiM112809; Fri, 28 Jun 2019 18:43:59 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=NoEAplNqwPTtngcrHp8WIH5Wq8xPo3S/3HyaDVonLxk=; b=Zld5oaujWs+K9ngaM3wLybiklAw4jmKRJeoOvJjpUJ7Gy3LJQpU8hgWZRGTOpwEHQi6s P0r5/SdQxYMTSEQiLNQuBXEo6DBzSt003YW6p13yaEJDRRCJlkySqGe36ukGV21Ff7Ir owuZH5QZG/MJjdWeU8/eeFmoa7bVMi5fhp+BkLJpYuGRlsD+VwodMcqzbkeKeDWrQFKK V52xSqSbCltA8ock7Mdlm85YrxrJJnCNUNaRERAznCxEmAIQsZxfC61vTCpoFql3p9a3 Rp+BHtWnLW72rBtmgWxcF7wDynDq0WT6kQuU4TU6nNv49rrhXXg9vCAOIziqpXaV6w/c Uw== Received: from userp3020.oracle.com (userp3020.oracle.com [156.151.31.79]) by userp2130.oracle.com with ESMTP id 2t9brtq4g0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 28 Jun 2019 18:43:59 +0000 Received: from pps.filterd (userp3020.oracle.com [127.0.0.1]) by userp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5SIhZsZ020745; Fri, 28 Jun 2019 18:43:58 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userp3020.oracle.com with ESMTP id 2tat7e3kdx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 28 Jun 2019 18:43:58 +0000 Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x5SIhurI031550; Fri, 28 Jun 2019 18:43:56 GMT MIME-Version: 1.0 Message-ID: <581e7cf3-a99f-415d-a999-3b2f3f419c8f@default> Date: Fri, 28 Jun 2019 11:43:55 -0700 (PDT) From: Drew Adams To: =?iso-8859-1?B?S+l2aW4gTGUgR291Z3VlYw==?= Subject: RE: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87a7e27gh5.fsf@gmail.com> <8736jujkvj.fsf@gmail.com> <32acf7a4-70d2-4c33-a3f5-18b082903d4a@default> <87ef3dvbgq.fsf@gmail.com> In-Reply-To: <87ef3dvbgq.fsf@gmail.com> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4861.0 (x86)] Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9302 signatures=668688 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906280211 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9302 signatures=668688 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906280211 X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > > (And too long - "highlighted chars won't be substituted" > > says the same thing as "the highlighted...".) >=20 > (Silly question: is it kosher to use contractions such as "won't" in > user-facing text? Or were you pointing out the superfluous "the" and/or > suggesting "chars" rather than "characters"?) Yes, and yes, and yes. Well, for the first "yes": I can't vouch for what's kosher. But yes. > > "Should highlighted chars be substituted? " > > > > or > > > > "Substitute highlighted occurrences of `*'? " >=20 > Mmm; currently this prompt is raised when the code detects that the > characters will *not* be substituted; answering "yes" makes Dired go on > with the command, answering "no" aborts. Yes, I assumed, in saying that, that the sense of the code would need to be reversed if the question was put that way. The question should be in a form that's easiest for users to understand and not misunderstand, if that's feasible in terms of code. > If we phrased the question like you suggest, we should probably change > the code to actually perform the substitutions should the user answer > "yes". Yes, that's what I meant. But that wording was just a casual suggestion, to get the point across. Someone (e.g. you) might well come up with something better. > > 1. It's not clear to me what someone will understand > > by "substituted" here. What would (otherwise) be > > substituted for what, where, and for what purpose? > > What substitution are we talking about, and how > > would a user be expected to know what we mean, here? >=20 > Right. Not sure how to make things clearer without quoting > dired-do-shell-command's documentation, which would make the prompt > quite verbose. Maybe someone else has a suggestion. It's worth working on, I think. > > 2. Are there multiple different "characterS" involved, > > or is the confirmation about only _one_ character, > > in (possibly) multiple locations - occurrences of > > one char? >=20 > One character in (possibly) multiple locations. That's what I thought. Then don't say chars (plural). > > 3. Is it the case that the new prompt does not, itself, > > show the character? Do you have to look elsewhere > > to see which char or chars(?) are meant by the > > prompt? Shouldn't the prompt itself show the char? >=20 > It does; the prompt shows the full command, and applies the warning face > to the character(s). Good. > > A final comment, which I'm not sure is relevant: > > > > We should not, in any case, _rely_ on any > > highlighting to get across meaning (semantics). > > Highlighting should always be an extra - a > > nice-to-have. Some users will not see the > > highlighting - it cannot be the only thing that > > gets the intended meaning across. > > > > (Again, I'm not saying that we _are_ relying on > > highlighting this way. I just want to be sure > > we're not. We don't want to unnecessarily > > introduce an accessibility problem.) >=20 > With the current patches, we absolutely totally completely _would_ rely > on highlighting to get across semantics. Thank you for spelling it out > as an accessibility problem; that kind of confirms my nagging feeling > that the highlighting method has an unfavorable benefit/cost ratio (IOW, > it's cute, but it might make things worse for some users). There is likely another way to make those occurrences stand out (in addition to, not instead of, highlighting). But I'm no expert on that. Maybe Eli has a suggestion. Emacs doesn't jump through zillions of hoops to try maximize accessibility. But it's good to keep it in mind and, at least when other things are equal, to DTRT in this regard. > So to conclude, these are the paths forward that I see: >=20 > (0. Drop the issue and grit my teeth when the warning shows up.) >=20 > 1. find a simple rephrasing, >=20 > 2. keep trying to make a more elaborate prompt, only using some other > tricks to point out the characters. >=20 > Example of path 1: >=20 > > Confirm--do you mean to send `*' verbatim to the shell? You can drop "Confirm--". You could even drop "do you mean to". If a reply is required to the question (e.g. it's `y-or-n-p') then users cannot avoid it or miss it. > (I don't like this one because it sounds like "do you want us to quote > `*' to make sure the shell does not expand it?") >=20 > Example of path 2: >=20 > > Confirm--do you mean to send these characters as-is to the shell? > > sed -e 's/foo?/foo!/' -e 's/bar?/bar!' > > ^ ^ >=20 > (I.e. using '^' to denote the non-isolated characters; not sure how > clear it is that "these" refers to "the caracters underlined by a '^'") Much better, IMO. Again: drop "Confirm--do you mean to", and use "these occurrences of `?'", not "these characters". There is only one char, in perhaps multiple locations. And I do think the char (`?' or whatever) should be mentioned explicitly in the question, not just have its occurrences indicated in the command to be sent. (Thanks for working on this.) From debbugs-submit-bounces@debbugs.gnu.org Sat Jun 29 09:48:41 2019 Received: (at 35564) by debbugs.gnu.org; 29 Jun 2019 13:48:41 +0000 Received: from localhost ([127.0.0.1]:43629 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hhDia-00084S-Hh for submit@debbugs.gnu.org; Sat, 29 Jun 2019 09:48:41 -0400 Received: from mail-io1-f47.google.com ([209.85.166.47]:34379) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hhDiU-00084B-OJ for 35564@debbugs.gnu.org; Sat, 29 Jun 2019 09:48:38 -0400 Received: by mail-io1-f47.google.com with SMTP id k8so18706870iot.1 for <35564@debbugs.gnu.org>; Sat, 29 Jun 2019 06:48:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=VfZ+cNCpQ0nF+16vSpu/Aw0nhC2BGBqKPU0aLv6AoBM=; b=T4AeQn51ATcGp6rU77cqY5fqGsZ6acvf1jqOtP+EhrO67txmc7qAyRQQ4IdXRloHsw YfCsi2oyR7R85EHUzGzB8Av5Ie83B8wqNbe0PWlL+LGgXO5+xootkuy7kL7NQ2OAlzox 6Kg/sb8AU/aOxRAupanN5wK7s4KtKHH5pJ2TJ9kXSaeUM49U/yMIOmCgqaFN8tJBoeSM kBb0PbkF2xbf0ppK0XoikkRvEAM2jc61k5xnlAvlpCj0gwQ5++565uzz8DcUmKhq6euX nTtLmqovbHH1gNAUJXw2vzzaGKGsuIC9WG1lYGqIGyaaXgJBT0yZvTx0NEa+9ML0iN9u 1h6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=VfZ+cNCpQ0nF+16vSpu/Aw0nhC2BGBqKPU0aLv6AoBM=; b=kOYhgXU7GbcEr0TO8WpPEu3IKRJx5bGXLoLajX4HTJXpIaezfzUAvTQ45CR9VjXX3H EN+IM3aJUVSZ/7FTsV7FiLcVOYJgdN2JTzANrGNKj+sqWC5lik9ZzWUDpxKsoxzZNsjO cMP9x8Slx1BDXri1ffVPJ5X+Unz8ygQ9Xfog7bcEY3GcOwFVk4IS7bmcI2VnCV0C2BKe +225/n7k/6K/hde6hjBGQ9z2An1+VkC3+sgtqaVlse9/mkNm3w+6QL+pNkAgEqS1gGuA P40ghsMqDRrtst3j9lBHzRN/Dl1bIgIJp92izvS3bGiI/+D68rVOUCxz/iPpNq/6Q1eh hD7Q== X-Gm-Message-State: APjAAAVLDHv7GYGQkZs+bFN/xAzRd9unaOo9kr7AlniaI64Uu8+7ZuTo tgLjNDC2aEk0HLEtGLrabBk= X-Google-Smtp-Source: APXvYqyj7Xa+04GWUM24AEKMYTMC0eTLwhFT23QAcLuqvYG37WClvhW6syDeFVVSBnsUvtlxX+WRUw== X-Received: by 2002:a02:3c07:: with SMTP id m7mr18663047jaa.64.1561816107052; Sat, 29 Jun 2019 06:48:27 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id v13sm4364465ioq.13.2019.06.29.06.48.26 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 29 Jun 2019 06:48:26 -0700 (PDT) From: Noam Postavsky To: Drew Adams Subject: Re: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87a7e27gh5.fsf@gmail.com> <8736jujkvj.fsf@gmail.com> <32acf7a4-70d2-4c33-a3f5-18b082903d4a@default> <87ef3dvbgq.fsf@gmail.com> <581e7cf3-a99f-415d-a999-3b2f3f419c8f@default> Date: Sat, 29 Jun 2019 09:48:25 -0400 In-Reply-To: <581e7cf3-a99f-415d-a999-3b2f3f419c8f@default> (Drew Adams's message of "Fri, 28 Jun 2019 11:43:55 -0700 (PDT)") Message-ID: <87pnmw5wpi.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2.90 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Stefan Monnier , =?utf-8?Q?K=C3=A9vin?= Le Gouguec X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Drew Adams writes: >> > A final comment, which I'm not sure is relevant: >> > >> > We should not, in any case, _rely_ on any >> > highlighting to get across meaning (semantics). >> > Highlighting should always be an extra - a >> > nice-to-have. Some users will not see the >> > highlighting - it cannot be the only thing that >> > gets the intended meaning across. >> With the current patches, we absolutely totally completely _would_ rely >> on highlighting to get across semantics. Thank you for spelling it out >> as an accessibility problem; that kind of confirms my nagging feeling >> that the highlighting method has an unfavorable benefit/cost ratio (IOW, >> it's cute, but it might make things worse for some users). > There is likely another way to make those occurrences > stand out (in addition to, not instead of, highlighting). > But I'm no expert on that. Maybe Eli has a suggestion. > > Emacs doesn't jump through zillions of hoops to try > maximize accessibility. But it's good to keep it in > mind and, at least when other things are equal, to DTRT > in this regard. Yes, we should definitely be careful not to make accessibility worse; thank you for bringing this up Drew. >> 1. find a simple rephrasing, >>=20 >> > Confirm--do you mean to send `*' verbatim to the shell? >> (I don't like this one because it sounds like "do you want us to quote >> `*' to make sure the shell does not expand it?") >> 2. keep trying to make a more elaborate prompt, only using some other >> tricks to point out the characters. >>=20 >> > Confirm--do you mean to send these characters as-is to the shell? >> > sed -e 's/foo?/foo!/' -e 's/bar?/bar!' >> > ^ ^ >>=20 >> (I.e. using '^' to denote the non-isolated characters; not sure how >> clear it is that "these" refers to "the caracters underlined by a '^'") I don't know about the '^' trick, if the minibuffer window is narrow enough to cause line wrapping the result won't be very readable. And I doubt a screen reader would handle this kind of thing any better than highlighting (someone please correct me if I'm wrong about that). I like the use of "as-is to shell": short and clear. > Again: drop "Confirm--do you mean to", and use > "these occurrences of `?'", not "these > characters". There is only one char, in perhaps > multiple locations. > > And I do think the char (`?' or whatever) should > be mentioned explicitly in the question, not just > have its occurrences indicated in the command to > be sent. Agreed on both these points. Updated patch is below, it produces prompts like these (still using highlighting): echo foo* Send 1 occurence of =E2=80=98*=E2=80=99 as-is to shell? (y or n) echo foo* bar* * Send 2 occurences of =E2=80=98*=E2=80=99 as-is to shell? (y or n) The last case (where there are both as-is and substituted "*") isn't so great without highlighting (you have to count the "*"s and work out if something unexpected is happening), but I think it's at least not worse than the current situation. --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=0003-Dedup-dired-aux-isolated-char-searching-Bug-35564.patch Content-Description: patch >From e339ad7d83025764645ed9101769467139390432 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 27 Jun 2019 19:15:56 -0400 Subject: [PATCH 3/3] Dedup dired-aux isolated char searching (Bug#35564) * lisp/dired-aux.el (dired-isolated-string-re): Use explicitly numbered groups. (dired--star-or-qmark-p): Add START parameter. Make sure to return the first isolated match. (dired--no-subst-prompt): Operate on a list of positions rather than searching again for isolated chars. Shorten prompt, and include the character being asked about in the question (to make it clearer, and in case the user can't see the fontification for whatever reason, e.g., screen reader). (dired--isolated-char-p): Remove. (dired--need-confirm-positions): New function. (dired-do-shell-command): Use it. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p): Remove. (dired-test-highlight-metachar): Adjust to new functions. Make sure that `*` isn't considered isolated. --- lisp/dired-aux.el | 113 ++++++++++++++++++++----------------------- test/lisp/dired-aux-tests.el | 31 ++++++------ 2 files changed, 67 insertions(+), 77 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 079e4f102f..47e1d38223 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -60,60 +60,60 @@ dired-isolated-string-re of a string followed/prefixed with an space. The regexp capture the preceding blank, STRING and the following blank as the groups 1, 2 and 3 respectively." - (format "\\(\\`\\|[ \t]\\)\\(%s\\)\\([ \t]\\|\\'\\)" string)) + (format "\\(?1:\\`\\|[ \t]\\)\\(?2:%s\\)\\(?3:[ \t]\\|\\'\\)" string)) -(defun dired--star-or-qmark-p (string match &optional keep) +(defun dired--star-or-qmark-p (string match &optional keep start) "Return non-nil if STRING contains isolated MATCH or `\\=`?\\=`'. MATCH should be the strings \"?\", `\\=`?\\=`', \"*\" or nil. The latter means STRING contains either \"?\" or `\\=`?\\=`' or \"*\". If optional arg KEEP is non-nil, then preserve the match data. Otherwise, this function changes it and saves MATCH as the second match group. +START is the position to start matching from. Isolated means that MATCH is surrounded by spaces or at the beginning/end of STRING followed/prefixed with an space. A match to `\\=`?\\=`', isolated or not, is also valid." - (let ((regexps (list (dired-isolated-string-re (if match (regexp-quote match) "[*?]"))))) + (let ((regexp (dired-isolated-string-re (if match (regexp-quote match) "[*?]")))) (when (or (null match) (equal match "?")) - (setq regexps (append (list "\\(\\)\\(`\\?`\\)\\(\\)") regexps))) - (cl-some (lambda (x) - (funcall (if keep #'string-match-p #'string-match) x string)) - regexps))) - -(defun dired--isolated-char-p (command pos) - "Assert whether the character at POS is isolated within COMMAND. -A character is isolated if: -- it is surrounded by whitespace, the start of the command, or - the end of the command, -- it is surrounded by `\\=`' characters." - (let ((start (max 0 (1- pos))) - (char (string (aref command pos)))) - (and (string-match - (rx (or (seq (or bos blank) - (group-n 1 (literal char)) - (or eos blank)) - (seq ?` (group-n 1 (literal char)) ?`))) - command start) - (= pos (match-beginning 1))))) - -(defun dired--highlight-nosubst-char (command char) - "Highlight occurences of CHAR that are not isolated in COMMAND. -These occurences will not be substituted; they will be sent as-is -to the shell, which may interpret them as wildcards." - (save-match-data - (let ((highlighted (substring-no-properties command)) - (pos 0)) - (while (string-match (regexp-quote char) command pos) - (let ((start (match-beginning 0)) - (end (match-end 0))) - (unless (dired--isolated-char-p command start) - (add-face-text-property start end 'warning nil highlighted)) - (setq pos end))) - highlighted))) - -(defun dired--no-subst-prompt (command char) - (let ((highlighted-command (dired--highlight-nosubst-char command char)) - (prompt "Confirm--the highlighted characters will not be substituted:")) - (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + (cl-callf concat regexp "\\|\\(?1:\\)\\(?2:`\\?`\\)\\(?3:\\)")) + (funcall (if keep #'string-match-p #'string-match) regexp string start))) + +(defun dired--need-confirm-positions (command string) + "Search for non-isolated matches of STRING in COMMAND. +Return a list of positions that match STRING, but would not be +considered \"isolated\" by `dired--star-or-qmark-p'." + (cl-assert (= (length string) 1)) + (let ((start 0) + (isolated-char-positions nil) + (confirm-positions nil) + (regexp (regexp-quote string))) + ;; Collect all ? and * surrounded by spaces and `?`. + (while (dired--star-or-qmark-p command string nil start) + (push (cons (match-beginning 2) (match-end 2)) + isolated-char-positions) + (setq start (match-end 2))) + ;; Now collect any remaining ? and *. + (setq start 0) + (while (string-match regexp command start) + (unless (cl-member (match-beginning 0) isolated-char-positions + :test (lambda (pos match) + (<= (car match) pos (cdr match)))) + (push (match-beginning 0) confirm-positions)) + (setq start (match-end 0))) + confirm-positions)) + +(defun dired--no-subst-prompt (char-positions command) + (cl-callf substring-no-properties command) + (dolist (pos char-positions) + (add-face-text-property pos (1+ pos) 'warning nil command)) + (concat command "\n" + (format-message + (ngettext "Send %d occurence of `%s' as-is to shell?" + "Send %d occurences of `%s' as-is to shell?" + (length char-positions)) + (length char-positions) + (propertize (string (aref command (car char-positions))) + 'face 'warning)))) ;;;###autoload (defun dired-diff (file &optional switches) @@ -779,26 +779,19 @@ dired-do-shell-command (dired-read-shell-command "! on %s: " current-prefix-arg files) current-prefix-arg files))) - (cl-flet ((need-confirm-p - (cmd str) - (let ((res cmd) - (regexp (regexp-quote str))) - ;; Drop all ? and * surrounded by spaces and `?`. - (while (and (string-match regexp res) - (dired--star-or-qmark-p res str)) - (setq res (replace-match "" t t res 2))) - (string-match regexp res)))) (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) + (confirmations nil) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. - (ok (cond ((not (or on-each no-subst)) - (error "You can not combine `*' and `?' substitution marks")) - ((need-confirm-p command "*") - (y-or-n-p (dired--no-subst-prompt command "*"))) - ((need-confirm-p command "?") - (y-or-n-p (dired--no-subst-prompt command "?"))) - (t)))) + (ok (cond + ((not (or on-each no-subst)) + (error "You can not combine `*' and `?' substitution marks")) + ((setq confirmations (dired--need-confirm-positions command "*")) + (y-or-n-p (dired--no-subst-prompt confirmations command))) + ((setq confirmations (dired--need-confirm-positions command "?")) + (y-or-n-p (dired--no-subst-prompt confirmations command))) + (t)))) (cond ((not ok) (message "Command canceled")) (t (if on-each @@ -809,7 +802,7 @@ dired-do-shell-command nil file-list) ;; execute the shell command (dired-run-shell-command - (dired-shell-stuff-it command file-list nil arg)))))))) + (dired-shell-stuff-it command file-list nil arg))))))) ;; Might use {,} for bash or csh: (defvar dired-mark-prefix "" diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 80b6393931..3f4bfffaf6 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,34 +114,31 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) -(ert-deftest dired-test-isolated-char-p () - (should (dired--isolated-char-p "?" 0)) - (should (dired--isolated-char-p "? " 0)) - (should (dired--isolated-char-p " ?" 1)) - (should (dired--isolated-char-p " ? " 1)) - (should (dired--isolated-char-p "foo bar ? baz" 8)) - (should (dired--isolated-char-p "foo -i`?`" 7)) - (should-not (dired--isolated-char-p "foo `bar`?" 9)) - (should-not (dired--isolated-char-p "foo 'bar?'" 8)) - (should-not (dired--isolated-char-p "foo bar?baz" 7)) - (should-not (dired--isolated-char-p "foo bar?" 7))) - (ert-deftest dired-test-highlight-metachar () "Check that non-isolated meta-characters are highlighted" (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") - (result (dired--highlight-nosubst-char command "?"))) + (prompt (dired--no-subst-prompt + command + (dired--need-confirm-positions command "?"))) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 14 'face nil result)) (should (equal 'warning (get-text-property 15 'face result))) (should-not (text-property-not-all 16 28 'face nil result)) (should (equal 'warning (get-text-property 29 'face result))) (should-not (text-property-not-all 30 39 'face nil result))) - (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") - (result (dired--highlight-nosubst-char command "*"))) + ;; Note that `?` is considered isolated, but `*` is not. + (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (prompt (dired--no-subst-prompt + command + (dired--need-confirm-positions command "*"))) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 10 'face nil result)) (should (equal 'warning (get-text-property 11 'face result))) (should-not (text-property-not-all 12 23 'face nil result)) - (should (equal 'warning (get-text-property 24 'face result))) - (should-not (text-property-not-all 25 29 'face nil result)))) + (should (equal 'warning (get-text-property 25 'face result))) + (should-not (text-property-not-all 26 32 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.11.0 --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sat Jun 29 10:13:40 2019 Received: (at 35564) by debbugs.gnu.org; 29 Jun 2019 14:13:40 +0000 Received: from localhost ([127.0.0.1]:44764 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hhE6m-0000Sh-88 for submit@debbugs.gnu.org; Sat, 29 Jun 2019 10:13:40 -0400 Received: from eggs.gnu.org ([209.51.188.92]:47506) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hhE6h-0000SS-PY for 35564@debbugs.gnu.org; Sat, 29 Jun 2019 10:13:36 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:49027) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hhE6b-0002Fy-EM; Sat, 29 Jun 2019 10:13:29 -0400 Received: from [176.228.60.248] (port=4299 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1hhE6Y-0000JY-74; Sat, 29 Jun 2019 10:13:28 -0400 Date: Sat, 29 Jun 2019 17:13:15 +0300 Message-Id: <83pnmwfpj8.fsf@gnu.org> From: Eli Zaretskii To: Drew Adams In-reply-to: <581e7cf3-a99f-415d-a999-3b2f3f419c8f@default> (message from Drew Adams on Fri, 28 Jun 2019 11:43:55 -0700 (PDT)) Subject: Re: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87a7e27gh5.fsf@gmail.com> <8736jujkvj.fsf@gmail.com> <32acf7a4-70d2-4c33-a3f5-18b082903d4a@default> <87ef3dvbgq.fsf@gmail.com> <581e7cf3-a99f-415d-a999-3b2f3f419c8f@default> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, npostavs@gmail.com, monnier@iro.umontreal.ca, kevin.legouguec@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > Date: Fri, 28 Jun 2019 11:43:55 -0700 (PDT) > From: Drew Adams > Cc: 35564@debbugs.gnu.org, Noam Postavsky , > Stefan Monnier > > > > We should not, in any case, _rely_ on any > > > highlighting to get across meaning (semantics). > > > Highlighting should always be an extra - a > > > nice-to-have. Some users will not see the > > > highlighting - it cannot be the only thing that > > > gets the intended meaning across. > > > > > > (Again, I'm not saying that we _are_ relying on > > > highlighting this way. I just want to be sure > > > we're not. We don't want to unnecessarily > > > introduce an accessibility problem.) > > > > With the current patches, we absolutely totally completely _would_ rely > > on highlighting to get across semantics. Thank you for spelling it out > > as an accessibility problem; that kind of confirms my nagging feeling > > that the highlighting method has an unfavorable benefit/cost ratio (IOW, > > it's cute, but it might make things worse for some users). > > There is likely another way to make those occurrences > stand out (in addition to, not instead of, highlighting). > But I'm no expert on that. Maybe Eli has a suggestion. We could both highlight and underline the relevant text. We already do that in other cases. From debbugs-submit-bounces@debbugs.gnu.org Sat Jun 29 10:30:18 2019 Received: (at 35564) by debbugs.gnu.org; 29 Jun 2019 14:30:18 +0000 Received: from localhost ([127.0.0.1]:44778 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hhEMs-0000sm-5D for submit@debbugs.gnu.org; Sat, 29 Jun 2019 10:30:18 -0400 Received: from aserp2120.oracle.com ([141.146.126.78]:60912) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hhEMm-0000rU-Rh for 35564@debbugs.gnu.org; Sat, 29 Jun 2019 10:30:13 -0400 Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5TESVN4117879; Sat, 29 Jun 2019 14:30:06 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=YKWfO8VqEn7nOO20lukKHFJdV9GXeqOKl+DxZPSeRtI=; b=FfOTp4vkgMjPRMnS5Y0RUbzIfP8wg7ODpoirkOyYvyDv2ToGfGQXEGkfsNBMCF8oQRM3 Sv9hB7pDlIW841oUfni2oYCdwM4cNol0kEnvmmvCdwhD7bi/rXdjsJ0HZKTYNM4aPQsJ viRCbxhpvb2eExx/1OuK1zwYeqOtFPBnTPcHNfUqGFB2zpmP3Qc82PMRR3LshY7VxsA9 XC0rNKgMOKQboC9mxIjMRPocu6ZstL74Y3Ltr5xSY9BCXDHTOOKesiQdzlHO7I2jyFGt ka4GGGK4JWefgaAHkicboB2H0DowNWVZgSgZX28kCIpKu4pERVQnFEUmH2fA8UIlBR7f 1Q== Received: from userp3030.oracle.com (userp3030.oracle.com [156.151.31.80]) by aserp2120.oracle.com with ESMTP id 2te5tb8b2q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sat, 29 Jun 2019 14:30:06 +0000 Received: from pps.filterd (userp3030.oracle.com [127.0.0.1]) by userp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5TEU47u067355; Sat, 29 Jun 2019 14:30:05 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userp3030.oracle.com with ESMTP id 2tdw3sd979-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sat, 29 Jun 2019 14:30:05 +0000 Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x5TEU2tR031080; Sat, 29 Jun 2019 14:30:02 GMT MIME-Version: 1.0 Message-ID: Date: Sat, 29 Jun 2019 07:30:01 -0700 (PDT) From: Drew Adams To: Noam Postavsky Subject: RE: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87a7e27gh5.fsf@gmail.com> <8736jujkvj.fsf@gmail.com> <32acf7a4-70d2-4c33-a3f5-18b082903d4a@default> <87ef3dvbgq.fsf@gmail.com> <581e7cf3-a99f-415d-a999-3b2f3f419c8f@default> <87pnmw5wpi.fsf@gmail.com> In-Reply-To: <87pnmw5wpi.fsf@gmail.com> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4861.0 (x86)] Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9303 signatures=668688 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906290182 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9303 signatures=668688 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906290182 X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Stefan Monnier , =?utf-8?B?S8OpdmluIExlIEdvdWd1ZWM=?= X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > >> > Confirm--do you mean to send these characters as-is to the shell? > >> > sed -e 's/foo?/foo!/' -e 's/bar?/bar!' > >> > ^ ^ >=20 > I don't know about the '^' trick, if the minibuffer window is narrow > enough to cause line wrapping the result won't be very readable. And I > doubt a screen reader would handle this kind of thing any better than > highlighting (someone please correct me if I'm wrong about that). Another possibility I almost mentioned is to use, by default, a face that uses `:box' or `:overline', or some such properties to make the char occurrences stand out without relying on color. That might at least help with some who have difficulty distinguishing color, but it's not an ideal solution either. I don't think we should try to jump through too many hoops about this. The main thing, I think, is to put the char itself in the sentence preceding the quoted command text. The use of `^' is not too bad, I think, even given the problems you mention. If the char occurrences that are problematic are not obvious then a user can cancel the command and check `*Messages*' for the full feedback. > Agreed on both these points. Updated patch is below, it produces > prompts like these (still using highlighting): >=20 > echo foo* > Send 1 occurence of =E2=80=98*=E2=80=99 as-is to shell? (y or n) >=20 > echo foo* bar* * > Send 2 occurences of =E2=80=98*=E2=80=99 as-is to shell? (y or n) Good. But "occurrences", not "occurences". > The last case (where there are both as-is and substituted "*") isn't so > great without highlighting (you have to count the "*"s and work out if > something unexpected is happening), but I think it's at least not worse > than the current situation. I vote for also adding the ^ indications underneath. If you think that is too often too problematic then maybe do something like one of these: 1. Give users a way to opt out or to remove that on demand. 2. Automatically remove it, based on window width, whether there are multiple lines, or whatever. But this should be controllable by a user (e.g. an option). Agreed about use of screenreaders. Users should be able to turn off the ^ indicators. From debbugs-submit-bounces@debbugs.gnu.org Wed Jul 03 15:47:55 2019 Received: (at 35564) by debbugs.gnu.org; 3 Jul 2019 19:47:55 +0000 Received: from localhost ([127.0.0.1]:50125 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hilEQ-0000F4-3v for submit@debbugs.gnu.org; Wed, 03 Jul 2019 15:47:55 -0400 Received: from mail-wm1-f42.google.com ([209.85.128.42]:53849) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hilEN-0000Eq-Q3 for 35564@debbugs.gnu.org; Wed, 03 Jul 2019 15:47:53 -0400 Received: by mail-wm1-f42.google.com with SMTP id x15so3407617wmj.3 for <35564@debbugs.gnu.org>; Wed, 03 Jul 2019 12:47:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=SuiLqm/GZdtL86R6S+DZYlTuvvvjt7b15eGKwHTdBqM=; b=RgZ/eouFy9pWpZgWWAEPPnu2oq9vpteDj0q9WMPsaDAB0Vf8F3Dkh/AJVpvvkhf/Zw JRsCDCofPNui/dLvLRbC9CD68tgr/TAoXs4QSia8dD8qmyI9VXmj8cl0ti3+lSxrcMhT PTT0uqE4dpr9QS8GIPv5atr+cBslRWjQSTUn6/WOnaNW0a6NSsZqbgWQo+CjHAeOlGC7 LCdJXCPVLGCWwqo84NzmJv6jLLXxEf+cPSjCzs1CVJvQucMtVyf3FBsekN79IgkBGWHR F+yawnRPWAmcxSyQnrMC/CPA4ZoySKkwLms7puZnjKH5nGpekjbpHrU8WN4eD/p7YgBO lCiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=SuiLqm/GZdtL86R6S+DZYlTuvvvjt7b15eGKwHTdBqM=; b=iM7Ez9zWJ6m0kUWteQdIccmVwMiLPpi7cHc0D5BGC+BThzUppY+m3FvKgUoS7jUXQL njxlixzTZxbXUJIHJcLAwaKgPfzCtWKyuQ4qqe4Yld4KnNrd7JjKJGazXSbuT6M+twHh OplDXy4zGzTIsqk0823tW79+r6FrMCJgrzxvfygWGbONezIKfFUTXAY/ve0gphod2Q8w 5o9UR+nZDLSSzeZpcf5hI3ca7Jly3OB+lFOHETjVIS0wwjZMs3sViOZSk2aX1Z5rRUBL 7Vbnp5LVkYer1vDy9Q4mCI7q+yZ17OK0pMyLNV73JNV211P2CNASpbLt8EcRPR5q3X+1 grmA== X-Gm-Message-State: APjAAAUA+hXOPh4Pp9EuBTlQ/DZ2d7EltksqmQMFSzuy6GwVYpEfYbZa /KJd7IF2NOKLPXI6N1jdAG0= X-Google-Smtp-Source: APXvYqyHrKnQ3ockU2Lv16/f2RUyr2ZQIL6nudQ/nEBBAgNNUHjacMA88Kn+bIRidshTGtEK0EPf3g== X-Received: by 2002:a7b:cae2:: with SMTP id t2mr8904488wml.157.1562183265629; Wed, 03 Jul 2019 12:47:45 -0700 (PDT) Received: from my-little-tumbleweed (71.142.13.109.rev.sfr.net. [109.13.142.71]) by smtp.gmail.com with ESMTPSA id d24sm6840791wra.43.2019.07.03.12.47.44 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 03 Jul 2019 12:47:44 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: 35564@debbugs.gnu.org Subject: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> Date: Wed, 03 Jul 2019 21:47:40 +0200 In-Reply-To: <87h88cvpkj.fsf_-_@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Wed, 26 Jun 2019 08:16:44 +0200") Message-ID: <87imsinbmr.fsf_-_@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Eli Zaretskii , Stefan Monnier , Drew Adams , Noam Postavsky X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable This series of patches consists in - the same 2 patches as v3 - Noam's refactoring - some amendments ("occurrence", order of arguments in tests) - a proof-of-concept for marking the occurrences with '^' Here is a list of improvements that I plan on tackling Soonish=E2=84=A2 1. refrain from adding markers if the minibuffer is not wide enough, 2. use (:inherit '(warning underline)) instead of warning, so that - if the warning face has some underlining, it is used, - otherwise the underline face makes sure that we don't rely only on colors. Thank you all for your your reviews and your patience. Sorry I can't manage to take more time to work on this. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Preserve-text-properties-in-y-or-n-p-prompts.patch >From 1f1e6c974a56e834ee09446bac3ab41e6cd6f9af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:03:59 +0200 Subject: [PATCH 1/5] Preserve text properties in y-or-n-p prompts * lisp/subr.el (read--propertize-prompt): New function to append the prompt face to a string. (y-or-n-p): Use it instead of discarding potential text properties. (Bug#35564) --- lisp/subr.el | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lisp/subr.el b/lisp/subr.el index 4a1649f601..c59f13b24c 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2338,6 +2338,9 @@ memory-limit ;;;; Input and display facilities. +(defun read--propertize-prompt (prompt) + (add-face-text-property 0 (length prompt) 'minibuffer-prompt t prompt)) + (defconst read-key-empty-map (make-sparse-keymap)) (defvar read-key-delay 0.01) ;Fast enough for 100Hz repeat rate, hopefully. @@ -2675,14 +2678,14 @@ y-or-n-p (let* ((scroll-actions '(recenter scroll-up scroll-down scroll-other-window scroll-other-window-down)) (key - (let ((cursor-in-echo-area t)) + (let ((cursor-in-echo-area t) + (prompt (if (memq answer scroll-actions) + prompt + (concat "Please answer y or n. " prompt)))) (when minibuffer-auto-raise (raise-frame (window-frame (minibuffer-window)))) - (read-key (propertize (if (memq answer scroll-actions) - prompt - (concat "Please answer y or n. " - prompt)) - 'face 'minibuffer-prompt))))) + (read--propertize-prompt prompt) + (read-key prompt)))) (setq answer (lookup-key query-replace-map (vector key) t)) (cond ((memq answer '(skip act)) nil) -- 2.22.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-Tweak-dired-warning-about-wildcard-characters.patch >From 2fbda185484b45a9fa70518c064ad55b884387c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:19:44 +0200 Subject: [PATCH 2/5] Tweak dired warning about "wildcard" characters Non-isolated '?' and '*' characters may be quoted, or backslash-escaped; we do not know for a fact that the shell will interpret them as wildcards. Rephrase the prompt and highlight the characters so that the user sees exactly what we are talking about. * lisp/dired-aux.el (dired--isolated-char-p) (dired--highlight-nosubst-char, dired--no-subst-prompt): New functions. (dired-do-shell-command): Use them. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p) (dired-test-highlight-metachar): Test the new functions. (Bug#35564) --- lisp/dired-aux.el | 42 ++++++++++++++++++++++++++++++++---- test/lisp/dired-aux-tests.el | 28 ++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 5e4ec4d1ec..079e4f102f 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -79,6 +79,42 @@ dired--star-or-qmark-p (funcall (if keep #'string-match-p #'string-match) x string)) regexps))) +(defun dired--isolated-char-p (command pos) + "Assert whether the character at POS is isolated within COMMAND. +A character is isolated if: +- it is surrounded by whitespace, the start of the command, or + the end of the command, +- it is surrounded by `\\=`' characters." + (let ((start (max 0 (1- pos))) + (char (string (aref command pos)))) + (and (string-match + (rx (or (seq (or bos blank) + (group-n 1 (literal char)) + (or eos blank)) + (seq ?` (group-n 1 (literal char)) ?`))) + command start) + (= pos (match-beginning 1))))) + +(defun dired--highlight-nosubst-char (command char) + "Highlight occurences of CHAR that are not isolated in COMMAND. +These occurences will not be substituted; they will be sent as-is +to the shell, which may interpret them as wildcards." + (save-match-data + (let ((highlighted (substring-no-properties command)) + (pos 0)) + (while (string-match (regexp-quote char) command pos) + (let ((start (match-beginning 0)) + (end (match-end 0))) + (unless (dired--isolated-char-p command start) + (add-face-text-property start end 'warning nil highlighted)) + (setq pos end))) + highlighted))) + +(defun dired--no-subst-prompt (command char) + (let ((highlighted-command (dired--highlight-nosubst-char command char)) + (prompt "Confirm--the highlighted characters will not be substituted:")) + (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + ;;;###autoload (defun dired-diff (file &optional switches) "Compare file at point with FILE using `diff'. @@ -759,11 +795,9 @@ dired-do-shell-command (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((need-confirm-p command "*") - (y-or-n-p (format-message - "Confirm--do you mean to use `*' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "*"))) ((need-confirm-p command "?") - (y-or-n-p (format-message - "Confirm--do you mean to use `?' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "?"))) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ccd3192792..80b6393931 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,6 +114,34 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(ert-deftest dired-test-isolated-char-p () + (should (dired--isolated-char-p "?" 0)) + (should (dired--isolated-char-p "? " 0)) + (should (dired--isolated-char-p " ?" 1)) + (should (dired--isolated-char-p " ? " 1)) + (should (dired--isolated-char-p "foo bar ? baz" 8)) + (should (dired--isolated-char-p "foo -i`?`" 7)) + (should-not (dired--isolated-char-p "foo `bar`?" 9)) + (should-not (dired--isolated-char-p "foo 'bar?'" 8)) + (should-not (dired--isolated-char-p "foo bar?baz" 7)) + (should-not (dired--isolated-char-p "foo bar?" 7))) + +(ert-deftest dired-test-highlight-metachar () + "Check that non-isolated meta-characters are highlighted" + (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (result (dired--highlight-nosubst-char command "?"))) + (should-not (text-property-not-all 1 14 'face nil result)) + (should (equal 'warning (get-text-property 15 'face result))) + (should-not (text-property-not-all 16 28 'face nil result)) + (should (equal 'warning (get-text-property 29 'face result))) + (should-not (text-property-not-all 30 39 'face nil result))) + (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") + (result (dired--highlight-nosubst-char command "*"))) + (should-not (text-property-not-all 1 10 'face nil result)) + (should (equal 'warning (get-text-property 11 'face result))) + (should-not (text-property-not-all 12 23 'face nil result)) + (should (equal 'warning (get-text-property 24 'face result))) + (should-not (text-property-not-all 25 29 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.22.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0003-Dedup-dired-aux-isolated-char-searching-Bug-35564.patch >From 0ecd865a837665b6d7549f1a18eff3b46988a7dd Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 27 Jun 2019 19:15:56 -0400 Subject: [PATCH 3/5] Dedup dired-aux isolated char searching (Bug#35564) * lisp/dired-aux.el (dired-isolated-string-re): Use explicitly numbered groups. (dired--star-or-qmark-p): Add START parameter. Make sure to return the first isolated match. (dired--no-subst-prompt): Operate on a list of positions rather than searching again for isolated chars. Shorten prompt, and include the character being asked about in the question (to make it clearer, and in case the user can't see the fontification for whatever reason, e.g., screen reader). (dired--isolated-char-p): Remove. (dired--need-confirm-positions): New function. (dired-do-shell-command): Use it. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p): Remove. (dired-test-highlight-metachar): Adjust to new functions. Make sure that `*` isn't considered isolated. --- lisp/dired-aux.el | 113 ++++++++++++++++------------------- test/lisp/dired-aux-tests.el | 31 +++++----- 2 files changed, 67 insertions(+), 77 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 079e4f102f..47e1d38223 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -60,60 +60,60 @@ dired-isolated-string-re of a string followed/prefixed with an space. The regexp capture the preceding blank, STRING and the following blank as the groups 1, 2 and 3 respectively." - (format "\\(\\`\\|[ \t]\\)\\(%s\\)\\([ \t]\\|\\'\\)" string)) + (format "\\(?1:\\`\\|[ \t]\\)\\(?2:%s\\)\\(?3:[ \t]\\|\\'\\)" string)) -(defun dired--star-or-qmark-p (string match &optional keep) +(defun dired--star-or-qmark-p (string match &optional keep start) "Return non-nil if STRING contains isolated MATCH or `\\=`?\\=`'. MATCH should be the strings \"?\", `\\=`?\\=`', \"*\" or nil. The latter means STRING contains either \"?\" or `\\=`?\\=`' or \"*\". If optional arg KEEP is non-nil, then preserve the match data. Otherwise, this function changes it and saves MATCH as the second match group. +START is the position to start matching from. Isolated means that MATCH is surrounded by spaces or at the beginning/end of STRING followed/prefixed with an space. A match to `\\=`?\\=`', isolated or not, is also valid." - (let ((regexps (list (dired-isolated-string-re (if match (regexp-quote match) "[*?]"))))) + (let ((regexp (dired-isolated-string-re (if match (regexp-quote match) "[*?]")))) (when (or (null match) (equal match "?")) - (setq regexps (append (list "\\(\\)\\(`\\?`\\)\\(\\)") regexps))) - (cl-some (lambda (x) - (funcall (if keep #'string-match-p #'string-match) x string)) - regexps))) - -(defun dired--isolated-char-p (command pos) - "Assert whether the character at POS is isolated within COMMAND. -A character is isolated if: -- it is surrounded by whitespace, the start of the command, or - the end of the command, -- it is surrounded by `\\=`' characters." - (let ((start (max 0 (1- pos))) - (char (string (aref command pos)))) - (and (string-match - (rx (or (seq (or bos blank) - (group-n 1 (literal char)) - (or eos blank)) - (seq ?` (group-n 1 (literal char)) ?`))) - command start) - (= pos (match-beginning 1))))) - -(defun dired--highlight-nosubst-char (command char) - "Highlight occurences of CHAR that are not isolated in COMMAND. -These occurences will not be substituted; they will be sent as-is -to the shell, which may interpret them as wildcards." - (save-match-data - (let ((highlighted (substring-no-properties command)) - (pos 0)) - (while (string-match (regexp-quote char) command pos) - (let ((start (match-beginning 0)) - (end (match-end 0))) - (unless (dired--isolated-char-p command start) - (add-face-text-property start end 'warning nil highlighted)) - (setq pos end))) - highlighted))) - -(defun dired--no-subst-prompt (command char) - (let ((highlighted-command (dired--highlight-nosubst-char command char)) - (prompt "Confirm--the highlighted characters will not be substituted:")) - (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + (cl-callf concat regexp "\\|\\(?1:\\)\\(?2:`\\?`\\)\\(?3:\\)")) + (funcall (if keep #'string-match-p #'string-match) regexp string start))) + +(defun dired--need-confirm-positions (command string) + "Search for non-isolated matches of STRING in COMMAND. +Return a list of positions that match STRING, but would not be +considered \"isolated\" by `dired--star-or-qmark-p'." + (cl-assert (= (length string) 1)) + (let ((start 0) + (isolated-char-positions nil) + (confirm-positions nil) + (regexp (regexp-quote string))) + ;; Collect all ? and * surrounded by spaces and `?`. + (while (dired--star-or-qmark-p command string nil start) + (push (cons (match-beginning 2) (match-end 2)) + isolated-char-positions) + (setq start (match-end 2))) + ;; Now collect any remaining ? and *. + (setq start 0) + (while (string-match regexp command start) + (unless (cl-member (match-beginning 0) isolated-char-positions + :test (lambda (pos match) + (<= (car match) pos (cdr match)))) + (push (match-beginning 0) confirm-positions)) + (setq start (match-end 0))) + confirm-positions)) + +(defun dired--no-subst-prompt (char-positions command) + (cl-callf substring-no-properties command) + (dolist (pos char-positions) + (add-face-text-property pos (1+ pos) 'warning nil command)) + (concat command "\n" + (format-message + (ngettext "Send %d occurence of `%s' as-is to shell?" + "Send %d occurences of `%s' as-is to shell?" + (length char-positions)) + (length char-positions) + (propertize (string (aref command (car char-positions))) + 'face 'warning)))) ;;;###autoload (defun dired-diff (file &optional switches) @@ -779,26 +779,19 @@ dired-do-shell-command (dired-read-shell-command "! on %s: " current-prefix-arg files) current-prefix-arg files))) - (cl-flet ((need-confirm-p - (cmd str) - (let ((res cmd) - (regexp (regexp-quote str))) - ;; Drop all ? and * surrounded by spaces and `?`. - (while (and (string-match regexp res) - (dired--star-or-qmark-p res str)) - (setq res (replace-match "" t t res 2))) - (string-match regexp res)))) (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) + (confirmations nil) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. - (ok (cond ((not (or on-each no-subst)) - (error "You can not combine `*' and `?' substitution marks")) - ((need-confirm-p command "*") - (y-or-n-p (dired--no-subst-prompt command "*"))) - ((need-confirm-p command "?") - (y-or-n-p (dired--no-subst-prompt command "?"))) - (t)))) + (ok (cond + ((not (or on-each no-subst)) + (error "You can not combine `*' and `?' substitution marks")) + ((setq confirmations (dired--need-confirm-positions command "*")) + (y-or-n-p (dired--no-subst-prompt confirmations command))) + ((setq confirmations (dired--need-confirm-positions command "?")) + (y-or-n-p (dired--no-subst-prompt confirmations command))) + (t)))) (cond ((not ok) (message "Command canceled")) (t (if on-each @@ -809,7 +802,7 @@ dired-do-shell-command nil file-list) ;; execute the shell command (dired-run-shell-command - (dired-shell-stuff-it command file-list nil arg)))))))) + (dired-shell-stuff-it command file-list nil arg))))))) ;; Might use {,} for bash or csh: (defvar dired-mark-prefix "" diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 80b6393931..3f4bfffaf6 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,34 +114,31 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) -(ert-deftest dired-test-isolated-char-p () - (should (dired--isolated-char-p "?" 0)) - (should (dired--isolated-char-p "? " 0)) - (should (dired--isolated-char-p " ?" 1)) - (should (dired--isolated-char-p " ? " 1)) - (should (dired--isolated-char-p "foo bar ? baz" 8)) - (should (dired--isolated-char-p "foo -i`?`" 7)) - (should-not (dired--isolated-char-p "foo `bar`?" 9)) - (should-not (dired--isolated-char-p "foo 'bar?'" 8)) - (should-not (dired--isolated-char-p "foo bar?baz" 7)) - (should-not (dired--isolated-char-p "foo bar?" 7))) - (ert-deftest dired-test-highlight-metachar () "Check that non-isolated meta-characters are highlighted" (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") - (result (dired--highlight-nosubst-char command "?"))) + (prompt (dired--no-subst-prompt + command + (dired--need-confirm-positions command "?"))) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 14 'face nil result)) (should (equal 'warning (get-text-property 15 'face result))) (should-not (text-property-not-all 16 28 'face nil result)) (should (equal 'warning (get-text-property 29 'face result))) (should-not (text-property-not-all 30 39 'face nil result))) - (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") - (result (dired--highlight-nosubst-char command "*"))) + ;; Note that `?` is considered isolated, but `*` is not. + (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (prompt (dired--no-subst-prompt + command + (dired--need-confirm-positions command "*"))) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 10 'face nil result)) (should (equal 'warning (get-text-property 11 'face result))) (should-not (text-property-not-all 12 23 'face nil result)) - (should (equal 'warning (get-text-property 24 'face result))) - (should-not (text-property-not-all 25 29 'face nil result)))) + (should (equal 'warning (get-text-property 25 'face result))) + (should-not (text-property-not-all 26 32 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.22.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0004-fixup-Dedup-dired-aux-isolated-char-searching-Bug-35.patch >From 8944a2c77e04012593450edd391a0e4ac0be090d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 3 Jul 2019 21:29:38 +0200 Subject: [PATCH 4/5] fixup! Dedup dired-aux isolated char searching (Bug#35564) --- lisp/dired-aux.el | 4 ++-- test/lisp/dired-aux-tests.el | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 47e1d38223..7ea1191c49 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -108,8 +108,8 @@ dired--no-subst-prompt (add-face-text-property pos (1+ pos) 'warning nil command)) (concat command "\n" (format-message - (ngettext "Send %d occurence of `%s' as-is to shell?" - "Send %d occurences of `%s' as-is to shell?" + (ngettext "Send %d occurrence of `%s' as-is to shell?" + "Send %d occurrences of `%s' as-is to shell?" (length char-positions)) (length char-positions) (propertize (string (aref command (car char-positions))) diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 3f4bfffaf6..ff18edddb6 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -118,8 +118,8 @@ dired-test-highlight-metachar "Check that non-isolated meta-characters are highlighted" (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") (prompt (dired--no-subst-prompt - command - (dired--need-confirm-positions command "?"))) + (dired--need-confirm-positions command "?") + command)) (result (and (string-match (regexp-quote command) prompt) (match-string 0 prompt)))) (should-not (text-property-not-all 1 14 'face nil result)) @@ -130,8 +130,8 @@ dired-test-highlight-metachar ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") (prompt (dired--no-subst-prompt - command - (dired--need-confirm-positions command "*"))) + (dired--need-confirm-positions command "*") + command)) (result (and (string-match (regexp-quote command) prompt) (match-string 0 prompt)))) (should-not (text-property-not-all 1 10 'face nil result)) -- 2.22.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0005-Add-markers-below-non-isolated-chars-in-dired-prompt.patch >From 7f28faa497419aeda4fed6ec413b7d6060f2c203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 3 Jul 2019 21:17:57 +0200 Subject: [PATCH 5/5] Add '^' markers below non-isolated chars in dired prompt * lisp/dired-aux.el (dired--mark-positions): New function. (dired--no-subst-prompt): Use it. * test/lisp/dired-aux-tests.el (dired-test-highlight-metachar): Add assertion for '^' marker positions. (Bug#35564) --- lisp/dired-aux.el | 25 +++++++++++++++++-------- test/lisp/dired-aux-tests.el | 8 ++++++-- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 7ea1191c49..cc11f2674f 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -102,18 +102,27 @@ dired--need-confirm-positions (setq start (match-end 0))) confirm-positions)) +(defun dired--mark-positions (positions) + (let* ((positions (sort positions '<)) + (markers (make-string (1+ (car (last positions))) ?\s))) + (dolist (pos positions) + (setf (aref markers pos) ?^)) + markers)) + (defun dired--no-subst-prompt (char-positions command) (cl-callf substring-no-properties command) (dolist (pos char-positions) (add-face-text-property pos (1+ pos) 'warning nil command)) - (concat command "\n" - (format-message - (ngettext "Send %d occurrence of `%s' as-is to shell?" - "Send %d occurrences of `%s' as-is to shell?" - (length char-positions)) - (length char-positions) - (propertize (string (aref command (car char-positions))) - 'face 'warning)))) + (let ((markers (dired--mark-positions char-positions))) + (concat command "\n" + markers "\n" + (format-message + (ngettext "Send %d occurrence of `%s' as-is to shell?" + "Send %d occurrences of `%s' as-is to shell?" + (length char-positions)) + (length char-positions) + (propertize (string (aref command (car char-positions))) + 'face 'warning))))) ;;;###autoload (defun dired-diff (file &optional switches) diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ff18edddb6..fbadfcbf12 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -117,6 +117,7 @@ dired-test-bug30624 (ert-deftest dired-test-highlight-metachar () "Check that non-isolated meta-characters are highlighted" (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (markers " ^ ^") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "?") command)) @@ -126,9 +127,11 @@ dired-test-highlight-metachar (should (equal 'warning (get-text-property 15 'face result))) (should-not (text-property-not-all 16 28 'face nil result)) (should (equal 'warning (get-text-property 29 'face result))) - (should-not (text-property-not-all 30 39 'face nil result))) + (should-not (text-property-not-all 30 39 'face nil result)) + (should (string-match (regexp-quote markers) prompt (1+ (length command))))) ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (markers " ^ ^") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "*") command)) @@ -138,7 +141,8 @@ dired-test-highlight-metachar (should (equal 'warning (get-text-property 11 'face result))) (should-not (text-property-not-all 12 23 'face nil result)) (should (equal 'warning (get-text-property 25 'face result))) - (should-not (text-property-not-all 26 32 'face nil result)))) + (should-not (text-property-not-all 26 32 'face nil result)) + (should (string-match (regexp-quote markers) prompt (1+ (length command)))))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.22.0 --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Fri Jul 12 11:10:40 2019 Received: (at 35564) by debbugs.gnu.org; 12 Jul 2019 15:10:40 +0000 Received: from localhost ([127.0.0.1]:40551 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hlxC2-0002cY-Jw for submit@debbugs.gnu.org; Fri, 12 Jul 2019 11:10:40 -0400 Received: from mail-wr1-f54.google.com ([209.85.221.54]:33931) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hlxBz-0002cK-RC for 35564@debbugs.gnu.org; Fri, 12 Jul 2019 11:10:37 -0400 Received: by mail-wr1-f54.google.com with SMTP id 31so10378345wrm.1 for <35564@debbugs.gnu.org>; Fri, 12 Jul 2019 08:10:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=8Dp3aRDzVK/VQ7aqInmPEGQkMWSgduvHehyBHhxEbgw=; b=ki/rpzNCFRS1jRp4EYJPNGYnwh6d18cxg58mOf7Kip8jMQFuRcZkKyw677nM8RFzfM X80J65ujHcHR1YnFtiqT403b9HydXsHKvjzoVWXmCn6RAZSLFnzWRCNCnaZx1/LZm+eG CBCG4DCep8GPpAKWGGsUp/WnA6lJ9PeYppHSl2+jns1TrzwThBOeCUaP3K8JqytNWHMX Lk3oNOwBO34hJRAl2jkLX/gR5VPFPi5lWRQWZDxd6HibkiOxenKegYxtDS4xfXbBzGki wQjyLtN1aSRDyeOZ+KqWrpY0mAFvPD3oZqKAxlLbAYX2V/tOIZXMCa2aYQSlsbJ/IJIj JoUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=8Dp3aRDzVK/VQ7aqInmPEGQkMWSgduvHehyBHhxEbgw=; b=L7wWF0hoFEMnePPp8ApK7p9knMh2WoF9Bh1xiWtXIhpkK+ffpnSdrlwl/+6i6CP3cX F0QI05WEBB4slp2i2LEKIyijB1s2kuMDSHaeM5p80O1pvXf2DYBHqmwCG82GDbw/iZja oKtHvdFhiZGSYTxwO+/q6hVHb9jXIYYIaFksyPVwhSnl+Zud6IvMfxVh+Dd5LOH7Tkte HEiUIJo7mg7sQHvt1hmLAeTeMA/ByOYWhfo1Y7OrtDvpHgiAMzkfBTpLfkpeluZLq96A QbWRcpZYscDykD5mzwuU2ESEm8dZEdhxeWynmiRRp/35DTIKiC+geRr79cCOPYYK8qqT l2yg== X-Gm-Message-State: APjAAAX8KIUNtxtVw0Z3REbXktT1T34RaNVN7NANwy2endF3MQUoDD7M DQtzhQXQYhGCdPErN2ewhHA= X-Google-Smtp-Source: APXvYqypcHQNVThzi814L7cvYAzVnSd62ynk86Cx5kd2LT3+aHZmRpM92hlVU3HVGxvpJqiqJTZY/w== X-Received: by 2002:adf:90e7:: with SMTP id i94mr11499889wri.224.1562944229980; Fri, 12 Jul 2019 08:10:29 -0700 (PDT) Received: from nc10-laptop ([80.12.63.125]) by smtp.gmail.com with ESMTPSA id m7sm7021801wrx.65.2019.07.12.08.10.27 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 12 Jul 2019 08:10:28 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: 35564@debbugs.gnu.org Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> Date: Fri, 12 Jul 2019 17:10:26 +0200 In-Reply-To: <87imsinbmr.fsf_-_@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Wed, 03 Jul 2019 21:47:40 +0200") Message-ID: <87y313z3tp.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Eli Zaretskii , Stefan Monnier , Drew Adams , Noam Postavsky X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Hello, I have now added '^' markers below the highlighted command, on condition that the echo area is wide enough not to wrap lines. Do we want to add some customizability (highlight face, whether or not to display '^' markers), or is this good enough for now? The patch series now includes: - two patches to make y-or-n-p preserve text properties and implement an initial version of highlighting, - Noam's refactoring patch, plus fixups, - one patch to add '^' markers, - one last patch to make tests less tedious to maintain. --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Preserve-text-properties-in-y-or-n-p-prompts.patch >From fbd41865515e13e35874e98a8847e1a67a9b956c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:03:59 +0200 Subject: [PATCH 1/6] Preserve text properties in y-or-n-p prompts * lisp/subr.el (read--propertize-prompt): New function to append the prompt face to a string. (y-or-n-p): Use it instead of discarding potential text properties. (Bug#35564) --- lisp/subr.el | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lisp/subr.el b/lisp/subr.el index 4a1649f601..c59f13b24c 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2338,6 +2338,9 @@ memory-limit ;;;; Input and display facilities. +(defun read--propertize-prompt (prompt) + (add-face-text-property 0 (length prompt) 'minibuffer-prompt t prompt)) + (defconst read-key-empty-map (make-sparse-keymap)) (defvar read-key-delay 0.01) ;Fast enough for 100Hz repeat rate, hopefully. @@ -2675,14 +2678,14 @@ y-or-n-p (let* ((scroll-actions '(recenter scroll-up scroll-down scroll-other-window scroll-other-window-down)) (key - (let ((cursor-in-echo-area t)) + (let ((cursor-in-echo-area t) + (prompt (if (memq answer scroll-actions) + prompt + (concat "Please answer y or n. " prompt)))) (when minibuffer-auto-raise (raise-frame (window-frame (minibuffer-window)))) - (read-key (propertize (if (memq answer scroll-actions) - prompt - (concat "Please answer y or n. " - prompt)) - 'face 'minibuffer-prompt))))) + (read--propertize-prompt prompt) + (read-key prompt)))) (setq answer (lookup-key query-replace-map (vector key) t)) (cond ((memq answer '(skip act)) nil) -- 2.20.1 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0002-Tweak-dired-warning-about-wildcard-characters.patch >From 802f14e186de7a8cf540b8d8c04155da1d983731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:19:44 +0200 Subject: [PATCH 2/6] Tweak dired warning about "wildcard" characters Non-isolated '?' and '*' characters may be quoted, or backslash-escaped; we do not know for a fact that the shell will interpret them as wildcards. Rephrase the prompt and highlight the characters so that the user sees exactly what we are talking about. * lisp/dired-aux.el (dired--isolated-char-p) (dired--highlight-nosubst-char, dired--no-subst-prompt): New functions. (dired-do-shell-command): Use them. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p) (dired-test-highlight-metachar): Test the new functions. (Bug#35564) --- lisp/dired-aux.el | 42 ++++++++++++++++++++++++++++++++---- test/lisp/dired-aux-tests.el | 28 ++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index d83e57d58d..d184598b92 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -79,6 +79,42 @@ dired--star-or-qmark-p (funcall (if keep #'string-match-p #'string-match) x string)) regexps))) +(defun dired--isolated-char-p (command pos) + "Assert whether the character at POS is isolated within COMMAND. +A character is isolated if: +- it is surrounded by whitespace, the start of the command, or + the end of the command, +- it is surrounded by `\\=`' characters." + (let ((start (max 0 (1- pos))) + (char (string (aref command pos)))) + (and (string-match + (rx (or (seq (or bos blank) + (group-n 1 (literal char)) + (or eos blank)) + (seq ?` (group-n 1 (literal char)) ?`))) + command start) + (= pos (match-beginning 1))))) + +(defun dired--highlight-nosubst-char (command char) + "Highlight occurences of CHAR that are not isolated in COMMAND. +These occurences will not be substituted; they will be sent as-is +to the shell, which may interpret them as wildcards." + (save-match-data + (let ((highlighted (substring-no-properties command)) + (pos 0)) + (while (string-match (regexp-quote char) command pos) + (let ((start (match-beginning 0)) + (end (match-end 0))) + (unless (dired--isolated-char-p command start) + (add-face-text-property start end 'warning nil highlighted)) + (setq pos end))) + highlighted))) + +(defun dired--no-subst-prompt (command char) + (let ((highlighted-command (dired--highlight-nosubst-char command char)) + (prompt "Confirm--the highlighted characters will not be substituted:")) + (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + ;;;###autoload (defun dired-diff (file &optional switches) "Compare file at point with FILE using `diff'. @@ -761,11 +797,9 @@ dired-do-shell-command (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((need-confirm-p command "*") - (y-or-n-p (format-message - "Confirm--do you mean to use `*' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "*"))) ((need-confirm-p command "?") - (y-or-n-p (format-message - "Confirm--do you mean to use `?' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "?"))) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ccd3192792..80b6393931 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,6 +114,34 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(ert-deftest dired-test-isolated-char-p () + (should (dired--isolated-char-p "?" 0)) + (should (dired--isolated-char-p "? " 0)) + (should (dired--isolated-char-p " ?" 1)) + (should (dired--isolated-char-p " ? " 1)) + (should (dired--isolated-char-p "foo bar ? baz" 8)) + (should (dired--isolated-char-p "foo -i`?`" 7)) + (should-not (dired--isolated-char-p "foo `bar`?" 9)) + (should-not (dired--isolated-char-p "foo 'bar?'" 8)) + (should-not (dired--isolated-char-p "foo bar?baz" 7)) + (should-not (dired--isolated-char-p "foo bar?" 7))) + +(ert-deftest dired-test-highlight-metachar () + "Check that non-isolated meta-characters are highlighted" + (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (result (dired--highlight-nosubst-char command "?"))) + (should-not (text-property-not-all 1 14 'face nil result)) + (should (equal 'warning (get-text-property 15 'face result))) + (should-not (text-property-not-all 16 28 'face nil result)) + (should (equal 'warning (get-text-property 29 'face result))) + (should-not (text-property-not-all 30 39 'face nil result))) + (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") + (result (dired--highlight-nosubst-char command "*"))) + (should-not (text-property-not-all 1 10 'face nil result)) + (should (equal 'warning (get-text-property 11 'face result))) + (should-not (text-property-not-all 12 23 'face nil result)) + (should (equal 'warning (get-text-property 24 'face result))) + (should-not (text-property-not-all 25 29 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.20.1 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0003-Dedup-dired-aux-isolated-char-searching-Bug-35564.patch >From e2d8c836bfa221205d7c72f8fc983258d24d02ce Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 27 Jun 2019 19:15:56 -0400 Subject: [PATCH 3/6] Dedup dired-aux isolated char searching (Bug#35564) * lisp/dired-aux.el (dired-isolated-string-re): Use explicitly numbered groups. (dired--star-or-qmark-p): Add START parameter. Make sure to return the first isolated match. (dired--no-subst-prompt): Operate on a list of positions rather than searching again for isolated chars. Shorten prompt, and include the character being asked about in the question (to make it clearer, and in case the user can't see the fontification for whatever reason, e.g., screen reader). (dired--isolated-char-p): Remove. (dired--need-confirm-positions): New function. (dired-do-shell-command): Use it. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p): Remove. (dired-test-highlight-metachar): Adjust to new functions. Make sure that `*` isn't considered isolated. --- lisp/dired-aux.el | 113 ++++++++++++++++------------------- test/lisp/dired-aux-tests.el | 31 +++++----- 2 files changed, 67 insertions(+), 77 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index d184598b92..32a4988498 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -60,60 +60,60 @@ dired-isolated-string-re of a string followed/prefixed with an space. The regexp capture the preceding blank, STRING and the following blank as the groups 1, 2 and 3 respectively." - (format "\\(\\`\\|[ \t]\\)\\(%s\\)\\([ \t]\\|\\'\\)" string)) + (format "\\(?1:\\`\\|[ \t]\\)\\(?2:%s\\)\\(?3:[ \t]\\|\\'\\)" string)) -(defun dired--star-or-qmark-p (string match &optional keep) +(defun dired--star-or-qmark-p (string match &optional keep start) "Return non-nil if STRING contains isolated MATCH or `\\=`?\\=`'. MATCH should be the strings \"?\", `\\=`?\\=`', \"*\" or nil. The latter means STRING contains either \"?\" or `\\=`?\\=`' or \"*\". If optional arg KEEP is non-nil, then preserve the match data. Otherwise, this function changes it and saves MATCH as the second match group. +START is the position to start matching from. Isolated means that MATCH is surrounded by spaces or at the beginning/end of STRING followed/prefixed with an space. A match to `\\=`?\\=`', isolated or not, is also valid." - (let ((regexps (list (dired-isolated-string-re (if match (regexp-quote match) "[*?]"))))) + (let ((regexp (dired-isolated-string-re (if match (regexp-quote match) "[*?]")))) (when (or (null match) (equal match "?")) - (setq regexps (append (list "\\(\\)\\(`\\?`\\)\\(\\)") regexps))) - (cl-some (lambda (x) - (funcall (if keep #'string-match-p #'string-match) x string)) - regexps))) - -(defun dired--isolated-char-p (command pos) - "Assert whether the character at POS is isolated within COMMAND. -A character is isolated if: -- it is surrounded by whitespace, the start of the command, or - the end of the command, -- it is surrounded by `\\=`' characters." - (let ((start (max 0 (1- pos))) - (char (string (aref command pos)))) - (and (string-match - (rx (or (seq (or bos blank) - (group-n 1 (literal char)) - (or eos blank)) - (seq ?` (group-n 1 (literal char)) ?`))) - command start) - (= pos (match-beginning 1))))) - -(defun dired--highlight-nosubst-char (command char) - "Highlight occurences of CHAR that are not isolated in COMMAND. -These occurences will not be substituted; they will be sent as-is -to the shell, which may interpret them as wildcards." - (save-match-data - (let ((highlighted (substring-no-properties command)) - (pos 0)) - (while (string-match (regexp-quote char) command pos) - (let ((start (match-beginning 0)) - (end (match-end 0))) - (unless (dired--isolated-char-p command start) - (add-face-text-property start end 'warning nil highlighted)) - (setq pos end))) - highlighted))) - -(defun dired--no-subst-prompt (command char) - (let ((highlighted-command (dired--highlight-nosubst-char command char)) - (prompt "Confirm--the highlighted characters will not be substituted:")) - (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + (cl-callf concat regexp "\\|\\(?1:\\)\\(?2:`\\?`\\)\\(?3:\\)")) + (funcall (if keep #'string-match-p #'string-match) regexp string start))) + +(defun dired--need-confirm-positions (command string) + "Search for non-isolated matches of STRING in COMMAND. +Return a list of positions that match STRING, but would not be +considered \"isolated\" by `dired--star-or-qmark-p'." + (cl-assert (= (length string) 1)) + (let ((start 0) + (isolated-char-positions nil) + (confirm-positions nil) + (regexp (regexp-quote string))) + ;; Collect all ? and * surrounded by spaces and `?`. + (while (dired--star-or-qmark-p command string nil start) + (push (cons (match-beginning 2) (match-end 2)) + isolated-char-positions) + (setq start (match-end 2))) + ;; Now collect any remaining ? and *. + (setq start 0) + (while (string-match regexp command start) + (unless (cl-member (match-beginning 0) isolated-char-positions + :test (lambda (pos match) + (<= (car match) pos (cdr match)))) + (push (match-beginning 0) confirm-positions)) + (setq start (match-end 0))) + confirm-positions)) + +(defun dired--no-subst-prompt (char-positions command) + (cl-callf substring-no-properties command) + (dolist (pos char-positions) + (add-face-text-property pos (1+ pos) 'warning nil command)) + (concat command "\n" + (format-message + (ngettext "Send %d occurence of `%s' as-is to shell?" + "Send %d occurences of `%s' as-is to shell?" + (length char-positions)) + (length char-positions) + (propertize (string (aref command (car char-positions))) + 'face 'warning)))) ;;;###autoload (defun dired-diff (file &optional switches) @@ -781,26 +781,19 @@ dired-do-shell-command (dired-read-shell-command "! on %s: " current-prefix-arg files) current-prefix-arg files))) - (cl-flet ((need-confirm-p - (cmd str) - (let ((res cmd) - (regexp (regexp-quote str))) - ;; Drop all ? and * surrounded by spaces and `?`. - (while (and (string-match regexp res) - (dired--star-or-qmark-p res str)) - (setq res (replace-match "" t t res 2))) - (string-match regexp res)))) (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) + (confirmations nil) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. - (ok (cond ((not (or on-each no-subst)) - (error "You can not combine `*' and `?' substitution marks")) - ((need-confirm-p command "*") - (y-or-n-p (dired--no-subst-prompt command "*"))) - ((need-confirm-p command "?") - (y-or-n-p (dired--no-subst-prompt command "?"))) - (t)))) + (ok (cond + ((not (or on-each no-subst)) + (error "You can not combine `*' and `?' substitution marks")) + ((setq confirmations (dired--need-confirm-positions command "*")) + (y-or-n-p (dired--no-subst-prompt confirmations command))) + ((setq confirmations (dired--need-confirm-positions command "?")) + (y-or-n-p (dired--no-subst-prompt confirmations command))) + (t)))) (cond ((not ok) (message "Command canceled")) (t (if on-each @@ -811,7 +804,7 @@ dired-do-shell-command nil file-list) ;; execute the shell command (dired-run-shell-command - (dired-shell-stuff-it command file-list nil arg)))))))) + (dired-shell-stuff-it command file-list nil arg))))))) ;; Might use {,} for bash or csh: (defvar dired-mark-prefix "" diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 80b6393931..3f4bfffaf6 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,34 +114,31 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) -(ert-deftest dired-test-isolated-char-p () - (should (dired--isolated-char-p "?" 0)) - (should (dired--isolated-char-p "? " 0)) - (should (dired--isolated-char-p " ?" 1)) - (should (dired--isolated-char-p " ? " 1)) - (should (dired--isolated-char-p "foo bar ? baz" 8)) - (should (dired--isolated-char-p "foo -i`?`" 7)) - (should-not (dired--isolated-char-p "foo `bar`?" 9)) - (should-not (dired--isolated-char-p "foo 'bar?'" 8)) - (should-not (dired--isolated-char-p "foo bar?baz" 7)) - (should-not (dired--isolated-char-p "foo bar?" 7))) - (ert-deftest dired-test-highlight-metachar () "Check that non-isolated meta-characters are highlighted" (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") - (result (dired--highlight-nosubst-char command "?"))) + (prompt (dired--no-subst-prompt + command + (dired--need-confirm-positions command "?"))) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 14 'face nil result)) (should (equal 'warning (get-text-property 15 'face result))) (should-not (text-property-not-all 16 28 'face nil result)) (should (equal 'warning (get-text-property 29 'face result))) (should-not (text-property-not-all 30 39 'face nil result))) - (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") - (result (dired--highlight-nosubst-char command "*"))) + ;; Note that `?` is considered isolated, but `*` is not. + (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (prompt (dired--no-subst-prompt + command + (dired--need-confirm-positions command "*"))) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 10 'face nil result)) (should (equal 'warning (get-text-property 11 'face result))) (should-not (text-property-not-all 12 23 'face nil result)) - (should (equal 'warning (get-text-property 24 'face result))) - (should-not (text-property-not-all 25 29 'face nil result)))) + (should (equal 'warning (get-text-property 25 'face result))) + (should-not (text-property-not-all 26 32 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.20.1 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0004-fixup-Dedup-dired-aux-isolated-char-searching-Bug-35.patch >From 2b93d2984cfa6ad9a33376a198707ebeb9d851b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 3 Jul 2019 21:29:38 +0200 Subject: [PATCH 4/6] fixup! Dedup dired-aux isolated char searching (Bug#35564) --- lisp/dired-aux.el | 4 ++-- test/lisp/dired-aux-tests.el | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 32a4988498..75c3a8952a 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -108,8 +108,8 @@ dired--no-subst-prompt (add-face-text-property pos (1+ pos) 'warning nil command)) (concat command "\n" (format-message - (ngettext "Send %d occurence of `%s' as-is to shell?" - "Send %d occurences of `%s' as-is to shell?" + (ngettext "Send %d occurrence of `%s' as-is to shell?" + "Send %d occurrences of `%s' as-is to shell?" (length char-positions)) (length char-positions) (propertize (string (aref command (car char-positions))) diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 3f4bfffaf6..ff18edddb6 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -118,8 +118,8 @@ dired-test-highlight-metachar "Check that non-isolated meta-characters are highlighted" (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") (prompt (dired--no-subst-prompt - command - (dired--need-confirm-positions command "?"))) + (dired--need-confirm-positions command "?") + command)) (result (and (string-match (regexp-quote command) prompt) (match-string 0 prompt)))) (should-not (text-property-not-all 1 14 'face nil result)) @@ -130,8 +130,8 @@ dired-test-highlight-metachar ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") (prompt (dired--no-subst-prompt - command - (dired--need-confirm-positions command "*"))) + (dired--need-confirm-positions command "*") + command)) (result (and (string-match (regexp-quote command) prompt) (match-string 0 prompt)))) (should-not (text-property-not-all 1 10 'face nil result)) -- 2.20.1 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0005-Add-markers-below-non-isolated-chars-in-dired-prompt.patch >From 5f4b3ed76a0b89f7a3dc2120cd2f29a3e64037bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 3 Jul 2019 21:17:57 +0200 Subject: [PATCH 5/6] Add '^' markers below non-isolated chars in dired prompt * lisp/dired-aux.el (dired--mark-positions): New function. (dired--no-subst-prompt): Use it to show chars without overly relying on highlighting. (dired-do-shell-command): When the echo area is wide enough to display the command without wrapping it, add the markers. * test/lisp/dired-aux-tests.el (dired-test-highlight-metachar): Add assertion for '^' marker positions. (Bug#35564) --- lisp/dired-aux.el | 43 +++++++++++++++++++++-------- test/lisp/dired-aux-tests.el | 53 ++++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 28 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 75c3a8952a..262ce64938 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -102,18 +102,35 @@ dired--need-confirm-positions (setq start (match-end 0))) confirm-positions)) -(defun dired--no-subst-prompt (char-positions command) +(defun dired--mark-positions (positions) + (let ((markers (make-string + (1+ (apply #'max positions)) + ?\s))) + (dolist (pos positions) + (setf (aref markers pos) ?^)) + markers)) + +(defun dired--no-subst-prompt (char-positions command add-markers) (cl-callf substring-no-properties command) (dolist (pos char-positions) (add-face-text-property pos (1+ pos) 'warning nil command)) - (concat command "\n" - (format-message - (ngettext "Send %d occurrence of `%s' as-is to shell?" - "Send %d occurrences of `%s' as-is to shell?" - (length char-positions)) - (length char-positions) - (propertize (string (aref command (car char-positions))) - 'face 'warning)))) + ;; `y-or-n-p' adds some text to the beginning of the prompt when the + ;; user fails to answer 'y' or 'n'. The highlighted command thus + ;; cannot be put on the first line of the prompt, since the added + ;; text will shove the command to the right, and the '^' markers + ;; will become misaligned. + (apply #'concat + `("Confirm:\n" + ,command "\n" + ,@(when add-markers + (list (dired--mark-positions char-positions) "\n")) + ,(format-message + (ngettext "Send %d occurrence of `%s' as-is to shell?" + "Send %d occurrences of `%s' as-is to shell?" + (length char-positions)) + (length char-positions) + (propertize (string (aref command (car char-positions))) + 'face 'warning))))) ;;;###autoload (defun dired-diff (file &optional switches) @@ -784,15 +801,19 @@ dired-do-shell-command (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) (confirmations nil) + (short-enough (< (length command) + (window-width (minibuffer-window)))) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((setq confirmations (dired--need-confirm-positions command "*")) - (y-or-n-p (dired--no-subst-prompt confirmations command))) + (y-or-n-p (dired--no-subst-prompt confirmations command + short-enough))) ((setq confirmations (dired--need-confirm-positions command "?")) - (y-or-n-p (dired--no-subst-prompt confirmations command))) + (y-or-n-p (dired--no-subst-prompt confirmations command + short-enough))) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ff18edddb6..58b3def2f5 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -115,30 +115,49 @@ dired-test-bug30624 (kill-buffer buf))))) (ert-deftest dired-test-highlight-metachar () - "Check that non-isolated meta-characters are highlighted" + "Check that non-isolated meta-characters are highlighted." (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (markers " ^ ^") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "?") - command)) - (result (and (string-match (regexp-quote command) prompt) - (match-string 0 prompt)))) - (should-not (text-property-not-all 1 14 'face nil result)) - (should (equal 'warning (get-text-property 15 'face result))) - (should-not (text-property-not-all 16 28 'face nil result)) - (should (equal 'warning (get-text-property 29 'face result))) - (should-not (text-property-not-all 30 39 'face nil result))) + command + t)) + (lines (split-string prompt "\n")) + (highlit-command (nth 1 lines))) + (should (= (length lines) 4)) + (should (string-match (regexp-quote command) highlit-command)) + (should (string-match (regexp-quote markers) (nth 2 lines))) + (should-not (text-property-not-all 1 14 'face nil highlit-command)) + (should (equal 'warning (get-text-property 15 'face highlit-command))) + (should-not (text-property-not-all 16 28 'face nil highlit-command)) + (should (equal 'warning (get-text-property 29 'face highlit-command))) + (should-not (text-property-not-all 30 39 'face nil highlit-command))) ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (markers " ^ ^") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "*") - command)) - (result (and (string-match (regexp-quote command) prompt) - (match-string 0 prompt)))) - (should-not (text-property-not-all 1 10 'face nil result)) - (should (equal 'warning (get-text-property 11 'face result))) - (should-not (text-property-not-all 12 23 'face nil result)) - (should (equal 'warning (get-text-property 25 'face result))) - (should-not (text-property-not-all 26 32 'face nil result)))) + command + t)) + (lines (split-string prompt "\n")) + (highlit-command (nth 1 lines))) + (should (= (length lines) 4)) + (should (string-match (regexp-quote command) highlit-command)) + (should (string-match (regexp-quote markers) (nth 2 lines))) + (should-not (text-property-not-all 1 10 'face nil highlit-command)) + (should (equal 'warning (get-text-property 11 'face highlit-command))) + (should-not (text-property-not-all 12 23 'face nil highlit-command)) + (should (equal 'warning (get-text-property 25 'face highlit-command))) + (should-not (text-property-not-all 26 32 'face nil highlit-command)) + (let* ((command "sed 's/\\?/!/'") + (prompt (dired--no-subst-prompt + (dired--need-confirm-positions command "?") + command + nil)) + (lines (split-string prompt "\n")) + (highlit-command (nth 1 lines))) + (should (= (length lines) 3)) + (should (string-match (regexp-quote command) highlit-command)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.20.1 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0006-Simplify-highlighting-assertions.patch >From 086937da30b912e8c0f44e3c7e8e2f5545b4f687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 12 Jul 2019 16:10:54 +0200 Subject: [PATCH 6/6] Simplify highlighting assertions * test/lisp/dired-aux-tests.el (dired-test--check-highlighting): New function. (dired-test-highlight-metachar): Use it. (Bug#35564) --- test/lisp/dired-aux-tests.el | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 58b3def2f5..ba10c54332 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,6 +114,15 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(defun dired-test--check-highlighting (command positions) + (let ((start 1)) + (dolist (pos positions) + (should-not (text-property-not-all start (1- pos) 'face nil command)) + (should (equal 'warning (get-text-property pos 'face command))) + (setq start (1+ pos))) + (should-not (text-property-not-all + start (length command) 'face nil command)))) + (ert-deftest dired-test-highlight-metachar () "Check that non-isolated meta-characters are highlighted." (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") @@ -127,11 +136,7 @@ dired-test-highlight-metachar (should (= (length lines) 4)) (should (string-match (regexp-quote command) highlit-command)) (should (string-match (regexp-quote markers) (nth 2 lines))) - (should-not (text-property-not-all 1 14 'face nil highlit-command)) - (should (equal 'warning (get-text-property 15 'face highlit-command))) - (should-not (text-property-not-all 16 28 'face nil highlit-command)) - (should (equal 'warning (get-text-property 29 'face highlit-command))) - (should-not (text-property-not-all 30 39 'face nil highlit-command))) + (dired-test--check-highlighting highlit-command '(15 29))) ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") (markers " ^ ^") @@ -144,11 +149,7 @@ dired-test-highlight-metachar (should (= (length lines) 4)) (should (string-match (regexp-quote command) highlit-command)) (should (string-match (regexp-quote markers) (nth 2 lines))) - (should-not (text-property-not-all 1 10 'face nil highlit-command)) - (should (equal 'warning (get-text-property 11 'face highlit-command))) - (should-not (text-property-not-all 12 23 'face nil highlit-command)) - (should (equal 'warning (get-text-property 25 'face highlit-command))) - (should-not (text-property-not-all 26 32 'face nil highlit-command)) + (dired-test--check-highlighting highlit-command '(11 25))) (let* ((command "sed 's/\\?/!/'") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "?") @@ -157,7 +158,8 @@ dired-test-highlight-metachar (lines (split-string prompt "\n")) (highlit-command (nth 1 lines))) (should (= (length lines) 3)) - (should (string-match (regexp-quote command) highlit-command)))) + (should (string-match (regexp-quote command) highlit-command)) + (dired-test--check-highlighting highlit-command '(8)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.20.1 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Again, thank you for your patience and your reviews. PS: the prompt now looks like this ('?' characters are highlighted with the warning face): With markers: > Confirm: > sed 's/\?/!/' > ^ > Send 1 occurrence of =E2=80=98?=E2=80=99 as-is to shell? Without markers: > Confirm: > sed 's/\?/!/' > Send 1 occurrence of =E2=80=98?=E2=80=99 as-is to shell? I added the "Confirm:" line because - y-or-n-p adds "Please answer y or n. " before the prompt when the user fails to answer correctly, so the markers would not line up if the command remained on the first line, - y-or-n-p adds " (y or n)" after the prompt; I find it more legible to have the question next to this suffix, so I did not want to move the question to the first line. --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sun Jul 14 18:38:10 2019 Received: (at control) by debbugs.gnu.org; 14 Jul 2019 22:38:10 +0000 Received: from localhost ([127.0.0.1]:46178 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hmn8D-0008Ov-QP for submit@debbugs.gnu.org; Sun, 14 Jul 2019 18:38:10 -0400 Received: from mail-io1-f49.google.com ([209.85.166.49]:36274) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hmn8C-0008Og-Jq; Sun, 14 Jul 2019 18:38:09 -0400 Received: by mail-io1-f49.google.com with SMTP id o9so31288190iom.3; Sun, 14 Jul 2019 15:38:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=gVd6MgjY2f5nyK1eMu92+mm51aecyGVgcihQnyVBH9s=; b=Pf1m5KvElGbAx8EAnJsptkp1CUkypMB9eXRGL9eJwku7MUkZYwtKbYhpIMfYvXYc1+ S4Rya/ffp47JttzQ4JT3ke6PTwQY94LeCzm/myt0YiTq11kGKEhWobkv7bqxlPiwK3X2 a4PHFzA1rw8k1XUNMkQbudRz2gCy6OyCnFSeE1ylBWO0GZGw3poAhphDuFuq7/m/d2gO z6Fz25jiEXS820Ty3guuaeVSEzDP2NX77RrOtanDerS5D16gbw1XeoHxCsJedyHKeank G2GMiRKedwQEkMZR7qjM59ItTgz1J9+ida0hb8S6V9nOs3RDEwfEOGPafr45PmSo23AG /MQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=gVd6MgjY2f5nyK1eMu92+mm51aecyGVgcihQnyVBH9s=; b=X8JnenhMP/JMAQ8vAWew0NH8FWwy2tdwJZKLq9zbGEJqddhsQ01WnDaZkgWr+tCyMg 6Afo06zBBRZkN4FutfoNwCz5Z0lMh8bvldFFfvKAmj7dsvXECkSQjDrnW02gqjoejRif LTJFwVSaknV2KFkf3eqr4bk+ZwrvqnOvvh4L3izaim2AFp5Y5EA/8V7k2UCBOr5w/Sdz xwuvstP8HLKXljLYRrn7CHWFWr9o4PvRbxb6C1pyhGxT1b0sPwpnM2Nl9MKBAUTfyMrA Ua8wJm6D9Qd1YZanq6N++4q9zuXj6yYt9F7brtAtNIHcODitg2uEhOb6R+H3CvbKGmMj vF6Q== X-Gm-Message-State: APjAAAXH+uxLZr1NYjBjFHZPhDsFe4NfQ7tDhzAGR0jiKFvyb6UA5IE4 OL+Hwe4J1Q1mHTZ85K2ucVW7YNOs X-Google-Smtp-Source: APXvYqwW6ALUciZbBZWaPhvGURlWP+R76RkGbwM/uPJseDSbiIxh3es1VkpHHXXC5+/sBHzAxAgT9A== X-Received: by 2002:a02:cb4b:: with SMTP id k11mr24103469jap.109.1563143882804; Sun, 14 Jul 2019 15:38:02 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id y20sm12797465iol.34.2019.07.14.15.38.02 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 14 Jul 2019 15:38:02 -0700 (PDT) From: Noam Postavsky To: Lars Ingebrigtsen Subject: Re: bug#28969: 27.0.50; dired: Confirmation prompt for wildcard not surrounded by whitespace References: <87she833e1.fsf@web.de> <877e8kwbsn.fsf@mouse.gnus.org> Date: Sun, 14 Jul 2019 18:38:01 -0400 In-Reply-To: <877e8kwbsn.fsf@mouse.gnus.org> (Lars Ingebrigtsen's message of "Sun, 14 Jul 2019 23:23:20 +0200") Message-ID: <871rys1bue.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2.90 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: control Cc: Michael Heerdegen , 28969@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) merge 28969 35564 quit Lars Ingebrigtsen writes: > Michael Heerdegen writes: > >> the docstring of `dired-do-shell-command' says: >> >> | `*' and `?' when not surrounded by whitespace nor `\\=`' have no special >> | significance for `dired-do-shell-command', and are passed through >> | normally to the shell, but you must confirm first. >> >> However, the `y-or-n-p' prompts asks: >> >> "Confirm--do you mean to use `*' as a wildcard? " >> >> and >> >> "Confirm--do you mean to use `?' as a wildcard? " >> >> and you must answer with 'y' to let these not be treated as wildcards - >> if you answer with 'n' as the docstring suggests, the operation is >> aborted. So, with other words, I think the questions must be inverted. > > Hm... I don't quite follow you here... It says it has no significance > for the command, but just passes it through to the shell. Where, of > course, it has great significance. > > If you create the file 1-1, put "bar" in it, and say "! cat 1*1" on the > file, after you've answered "y", you'll get a buffer with "bar bar" in > it. > > So I think all this is correct? Unless I'm misreading you. The meaning of "wildcard" is a bit ambiguous in the prompt itself. There is another report about this in #35564, and patches to greatly enhance the prompt. https://debbugs.gnu.org/35564#104 From debbugs-submit-bounces@debbugs.gnu.org Sat Jul 27 07:20:54 2019 Received: (at 35564) by debbugs.gnu.org; 27 Jul 2019 11:20:54 +0000 Received: from localhost ([127.0.0.1]:43716 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrKkw-0003TC-62 for submit@debbugs.gnu.org; Sat, 27 Jul 2019 07:20:54 -0400 Received: from eggs.gnu.org ([209.51.188.92]:51033) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrKku-0003T0-NE for 35564@debbugs.gnu.org; Sat, 27 Jul 2019 07:20:52 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:38864) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hrKkl-0006Iu-0H; Sat, 27 Jul 2019 07:20:44 -0400 Received: from [176.228.60.248] (port=4098 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1hrKkh-00074P-W8; Sat, 27 Jul 2019 07:20:42 -0400 Date: Sat, 27 Jul 2019 14:20:31 +0300 Message-Id: <83wog3lo5c.fsf@gnu.org> From: Eli Zaretskii To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec In-reply-to: <87y313z3tp.fsf@gmail.com> (message from =?iso-8859-1?Q?K=E9v?= =?iso-8859-1?Q?in?= Le Gouguec on Fri, 12 Jul 2019 17:10:26 +0200) Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> MIME-version: 1.0 Content-type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, drew.adams@oracle.com, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > From: Kévin Le Gouguec > Cc: Eli Zaretskii , Stefan Monnier > , Drew Adams , Noam > Postavsky > Date: Fri, 12 Jul 2019 17:10:26 +0200 > > I have now added '^' markers below the highlighted command, on condition > that the echo area is wide enough not to wrap lines. > > Do we want to add some customizability (highlight face, whether or not > to display '^' markers), or is this good enough for now? > > > The patch series now includes: > > - two patches to make y-or-n-p preserve text properties and implement an > initial version of highlighting, > - Noam's refactoring patch, plus fixups, > - one patch to add '^' markers, > - one last patch to make tests less tedious to maintain. Any more comments, anyone? Is there anything in these changes that would warrant a NEWS entry? Thanks. From debbugs-submit-bounces@debbugs.gnu.org Sat Jul 27 13:26:37 2019 Received: (at 35564) by debbugs.gnu.org; 27 Jul 2019 17:26:37 +0000 Received: from localhost ([127.0.0.1]:45376 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrQSq-0006eG-Lh for submit@debbugs.gnu.org; Sat, 27 Jul 2019 13:26:36 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:32881) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrQSm-0006dy-To for 35564@debbugs.gnu.org; Sat, 27 Jul 2019 13:26:35 -0400 Received: by mail-wr1-f68.google.com with SMTP id n9so57616942wru.0 for <35564@debbugs.gnu.org>; Sat, 27 Jul 2019 10:26:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=G1gCwtMQmx9wibDYGZ7I2a8UWycoXunib42GtqBF54c=; b=irxCMfrkbSz6bJhBa4m1YrHvgQoiptD8FG3s43ulakskW6mXRqKzbJABMieB6A0QDA CH5D/XcH7hh/mVEDVEcDLZwUN0lrl28CITHd3Vta8BJeF6lLzGH2/FKrjiEm3XFPcbn/ UtwGnZ7U33kJHJW9afOdUsYyO1m8Kt15bS0XvC/BdgZN5rgpEp1noKnN7vSRHXXIDCeG UgTFiMAw+NU4VrykzsGAZoX2RvbFYRc8uzfasnTh3j+4n9ruMrELgeE5hoCSYLaMTw0+ v8wvCMZKYjR7Qswx6OztOKKRF/NlHfl+i9L6ixsko7dXMY6gQjg9+kelM2PbTX3ftyhb xWQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=G1gCwtMQmx9wibDYGZ7I2a8UWycoXunib42GtqBF54c=; b=ZTtAT4C/27P8bKwGr2JDlBUvOOX2//6R5xYqs3Pxx9Vz1CDvosCWCMyzzCf5+5UgMb AOHl2zC3kmAnwV6+h0uNvLJ//chYQomO83EZtbrxme66CZzCFU8eKYaYOHD2RUTkWbaG CSbmVHD9GeftUwYygEL2O/4wEfPzYhkiNapPB0AHgIlrkvkqgQ5Y/BrVsDBzoc9LEUMV ucFBrj5R5hLslhj5bXT0HEVZ8w6unrYlwBPK607ApHVuxnPTbsOaw7FMso/1gRzITDDV OeuoAjH7l8Ag2f2Y0wmR9t75sORHE9Ke3N6x8HTjMRhc25XbPNew5LV37/fGByyl3KWB nMNQ== X-Gm-Message-State: APjAAAWlcMv5087YvYw6eFZi7a3I/Eh+BVEnSwqCPyRqpmWLtPsMv2LZ 0xjjQ3suKZmGwiCgVUCp4k4= X-Google-Smtp-Source: APXvYqyfFDHZp2wipe/97mdC8rmLQaqtKavDWXto1hR7bCrNoahxQXnraduedZM2hnf89TvXEV5QBQ== X-Received: by 2002:adf:e790:: with SMTP id n16mr92005107wrm.120.1564248387148; Sat, 27 Jul 2019 10:26:27 -0700 (PDT) Received: from nc10-laptop (2a01cb04010fc800c8771fb97d0446e3.ipv6.abo.wanadoo.fr. [2a01:cb04:10f:c800:c877:1fb9:7d04:46e3]) by smtp.gmail.com with ESMTPSA id g10sm40992829wrw.60.2019.07.27.10.26.25 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 27 Jul 2019 10:26:26 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Eli Zaretskii Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> Date: Sat, 27 Jul 2019 19:26:25 +0200 In-Reply-To: <83wog3lo5c.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 27 Jul 2019 14:20:31 +0300") Message-ID: <87wog3pewu.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: michael_heerdegen@web.de, 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, drew.adams@oracle.com, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Eli Zaretskii writes: >> From: K=C3=A9vin Le Gouguec >> Cc: Eli Zaretskii , Stefan Monnier >> , Drew Adams , Noam >> Postavsky >> Date: Fri, 12 Jul 2019 17:10:26 +0200 >>=20 >> I have now added '^' markers below the highlighted command, on condition >> that the echo area is wide enough not to wrap lines. >>=20 >> Do we want to add some customizability (highlight face, whether or not >> to display '^' markers), or is this good enough for now? >>=20 >>=20 >> The patch series now includes: >>=20 >> - two patches to make y-or-n-p preserve text properties and implement an >> initial version of highlighting, >> - Noam's refactoring patch, plus fixups, >> - one patch to add '^' markers, >> - one last patch to make tests less tedious to maintain. > > Any more comments, anyone? Michael had some comments over at bug#28969, but no objections AFAICT. Michael, did you get the chance to try the patch out? > Is there anything in these changes that would warrant a NEWS entry? The changes are only cosmetic: the user interaction has not changed (tell Dired to run a command, press 'y' to confirm). The prompt is simply more verbose now. There are no new variables for the user to customize either, if I am not mistaken. NB: I squashed all those patches in [2], to make it easier to try the new prompt out. The squashed patch's commit message summarizes every change, and mentions both bugs; I don't know if it makes more sense to commit the series or the squashed patch to the repository. [1] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D28969#22 [2] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D28969#19 From debbugs-submit-bounces@debbugs.gnu.org Sat Jul 27 18:03:37 2019 Received: (at 35564) by debbugs.gnu.org; 27 Jul 2019 22:03:37 +0000 Received: from localhost ([127.0.0.1]:45528 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrUmv-0002K6-B0 for submit@debbugs.gnu.org; Sat, 27 Jul 2019 18:03:37 -0400 Received: from mail-wr1-f42.google.com ([209.85.221.42]:35564) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrUmt-0002Jr-6F for 35564@debbugs.gnu.org; Sat, 27 Jul 2019 18:03:35 -0400 Received: by mail-wr1-f42.google.com with SMTP id y4so57888739wrm.2 for <35564@debbugs.gnu.org>; Sat, 27 Jul 2019 15:03:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tcd-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=OmlGYtC7hF9thftNtcwEbyLaAkL3m5QM4ohsFra/T0E=; b=Ca4bQ7/v0YH+rX7GLxlWBR0fEnfW07Td5865WyfNOXlUxp8iYBY8GDj4br/zJsSU+e lemGtb/al6WngoiNOQP7Q0r4ImZRM1x9leXkXLg2bHjs2p6o2pJCMk8rHI/Ba2stTvoX OS6Y7tLvUBBU3vG7XfsunrwlXls2Vw4D5NJEAJvMgJHYwCtm+0dMRo8deOMHz6k34Scb GpdAVp/PYPHjSRTzZbO1Y1BeoGuUijrBmpkN9H5oQfvPKgsVaLCAKolbyW0IHEVGm8iP xzLTbWWymEal13LaaWeewo4oEG23Jpff6fRbk4iWfJv/DOm+X5Fkm5gfDQQcgqNctY8p lzmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=OmlGYtC7hF9thftNtcwEbyLaAkL3m5QM4ohsFra/T0E=; b=kLtAip63zcJKFNGv7sHUlj3Af8wavv4OVB1X0eCIOrxksBD55Ux31YcLN3P3AJvt4a kyI1I4qp37lJOG/ig21S2Zemg3M0UwIe3ZAhbujEclrc03AjMJQeQDYO2LUaJt63hs9+ yKcPzgVdBVhhM8eXjSAzS+mtvTMQkUz7y/+792HS9Y7Fo8NbI/i/GfvkhtJPHxMHijwh 8ShYhxP6UUJ6v1EvGGKQ15dGP8NxSExdS4+oTF5fsA+fHh7LYNfJ+VHR+nlhfvlLLimp nUg9EFzYEnj4uN/NiTZFGHcP07+9h1ld/NVkWJOt0Rhyd//+mk8j09utRxJpKUwvb4q6 q/VA== X-Gm-Message-State: APjAAAWa1oQxwIOp2KQl8/b7d7c+owsgn34Y/GxSMDcMbAXycK6sAGY3 I6rOHYnGExyP22fJs/prm81COw== X-Google-Smtp-Source: APXvYqxGru7mDzqf28He2x0Mg5x14UOju1tE512jOBMUsOJ/V6bc74k1cgvwjvBci42346/8vRo9qw== X-Received: by 2002:a5d:4f01:: with SMTP id c1mr28763092wru.43.1564265009374; Sat, 27 Jul 2019 15:03:29 -0700 (PDT) Received: from localhost ([2a02:8084:20e2:c380:92bd:1bfd:38fc:fae2]) by smtp.gmail.com with ESMTPSA id f192sm60235819wmg.30.2019.07.27.15.03.28 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Sat, 27 Jul 2019 15:03:28 -0700 (PDT) From: "Basil L. Contovounesios" To: Eli Zaretskii Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> Date: Sat, 27 Jul 2019 23:03:27 +0100 In-Reply-To: <83wog3lo5c.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 27 Jul 2019 14:20:31 +0300") Message-ID: <87imrn16fk.fsf@tcd.ie> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: npostavs@gmail.com, 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, =?utf-8?Q?K=C3=A9vin?= Le Gouguec X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Eli Zaretskii writes: > Any more comments, anyone? Just a couple of very minor questions from me: K=C3=A9vin Le Gouguec writes: > -(defun dired--no-subst-prompt (char-positions command) > +(defun dired--mark-positions (positions) > + (let ((markers (make-string > + (1+ (apply #'max positions)) Is POSITIONS guaranteed to be non-nil? (The max function takes at least one argument.) > Subject: [PATCH 6/6] Simplify highlighting assertions > > * test/lisp/dired-aux-tests.el (dired-test--check-highlighting): > New function. > (dired-test-highlight-metachar): Use it. Will this simplification hinder debugging of test failures? I don't have an opinion on the proposed change, it's just something to consider. > Again, thank you for your patience and your reviews. Thank you for working on this, --=20 Basil From debbugs-submit-bounces@debbugs.gnu.org Sat Jul 27 18:23:08 2019 Received: (at 35564) by debbugs.gnu.org; 27 Jul 2019 22:23:08 +0000 Received: from localhost ([127.0.0.1]:45537 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrV5o-0002op-BP for submit@debbugs.gnu.org; Sat, 27 Jul 2019 18:23:08 -0400 Received: from mout.web.de ([212.227.15.3]:56731) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrV5n-0002oN-A5 for 35564@debbugs.gnu.org; Sat, 27 Jul 2019 18:23:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1564266166; bh=OS7LlJ2m4qfpcc7zfhiD7GRgAE1hYLlUIuPsUV67k5c=; h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To; b=RxT8lq6zgpVTluTGiLNW2IKP3fzFKl3LvCue2wPwfP1QZGffCeq5RBvMZZVpm9RFR ti/ikyZ5TVR2RJMgJqM9eLysxCwk+tj8q3WP/RPUyq5kfKzrVQjaQ+hFfXVWENc7rN nyTD13ZjM3heQFa02Wwd1nLGSWQ8EO99CUE2EKIM= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from drachen.dragon ([92.208.178.242]) by smtp.web.de (mrweb003 [213.165.67.108]) with ESMTPSA (Nemesis) id 0LmLac-1iR6km1czi-00Zx7z; Sun, 28 Jul 2019 00:22:46 +0200 From: Michael Heerdegen To: =?utf-8?Q?K=C3=A9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> <87wog3pewu.fsf@gmail.com> Date: Sun, 28 Jul 2019 00:22:40 +0200 In-Reply-To: <87wog3pewu.fsf@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Sat, 27 Jul 2019 19:26:25 +0200") Message-ID: <87v9vndsnj.fsf@web.de> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:QVOz8vMhh2O4MMYrcDv81Y7MoqR3qu77PLn/nr0ReksnC5KG5Y7 9sCGyDmXH/insQtPnnDSCZSxFF00CpHnISW1SpGIooJqq5M6vCNmfmaosWH/sHjlrVNrIbg H7nrgVxk93qdwUet7XJNbTgypvPp4cVikZ1KcoL/eXRLefVn5pYGRxm9D9rAUK+tF4aJUvH hi43Mw8zYyXZ6Xe4MpVFw== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:u8uVTMYUUZU=:d8SSbOza89mL9jUPQRrfEv 3P+OhpBE66DZXVTR4Ug/z5djvUVi1LvOB9ksCVe303shGyRXAkK2Vtx8P2jZPPPzMrbQPoUk+ 7KuGwGbGj/GXoZTqblP9SrHK10l/4jkM9Zy1DRk5RotO1YvsQlXagEvu1J3qJ3QYL4+5ZZm4S Q/OPU7D4+3qlPM5fy3C0aU4mwBLk9d3Zzx9oXyXYw37jVbNl74g9rDzjLHL84O7eVtpYLgw71 2QuuhBei6+QPvwKkqNzYWJqsh/gYJ1llhYamELNXsq0MH942bfh4LfNwVapqP5T4SSu+Ovj0D J/4XkEb1/IkbIq4+5WCQRg0XSwE5c67jYw6jF2X0aanwJYop7S0say56Yyt2j0qsPTZBPPymh VjoA/EWD6OHodlW24ygNuYt553Id+umZSlG6acs4uD6KtgQpoyhvVY/gpH7LxWvIvTuLRpFmn 4gUjzGg1Db636SurKR2cuw3Y31imqbwsxgGq1mWg6nnGkj1LvrCFF0y6tf0x8nkA27uO2vgo1 uDOXkfiHZBfLCvi8FTrXCE2CZ2WvUKW6+ETytVo+fT4t8OqAEF6fyJDNajMJzDviQMj8GYdmg 21OmyyqNnQZkB4OnUeQxOfYvre8Q5XbdiHvRkbP2Yz4mUZ99aa1/7kZUm85PK/OqhIlzqZbMU zhj8T9MI2JiZaAm9X4R/YbnIaQiBBSmVrk/dgNntdBT4Mb0mZ5oPfozbfcUeeRdJ46gTaHJ5c c0spvb8/JpPXZybbdWeOlq77V77zyWCT9rAv2sfkawghSh3OJoLMa32VhBPogTmh2uY+UbV0D MEgHdjiyRc4IBocu+c59xdKSubqgJCtv0V+hzIWzqgfLrFwIbbHw6yvaHTEwExMHQvmXTLRJO rXJTmU+3GfvVUKzZ7optIjJyNRK7P+OXyiHbvnyqs+PefVZ6cPtBjGe/DljIzIPuEcZef87kO oS4NpR2+k7bf2pySZz1U7o6AqtCj1IMPSecEpwgHwZD5B3m0GKxT5QuDzxi91KtnQfqaQ8o+s pNRKXhg5G8xO2ATcHsntBuXjA8jpw1+BCibbot4vjwciZ4rYWu5+Q0FY5xdQ+mY4LNoirPOxy OynueRUojVWZzil/nXYMRhuBSIPNEkeZ9o+ X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Eli Zaretskii , 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) K=C3=A9vin Le Gouguec writes: > Michael, did you get the chance to try the patch out? I skimmed through the changes and have installed it, but I didn't yet try it. Will do ASAP, hopefully tonight. Michael. From debbugs-submit-bounces@debbugs.gnu.org Sat Jul 27 19:32:32 2019 Received: (at 35564) by debbugs.gnu.org; 27 Jul 2019 23:32:32 +0000 Received: from localhost ([127.0.0.1]:45577 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrWAw-0004bK-Nd for submit@debbugs.gnu.org; Sat, 27 Jul 2019 19:32:31 -0400 Received: from mail-wr1-f65.google.com ([209.85.221.65]:45791) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrWAt-0004b4-Nk for 35564@debbugs.gnu.org; Sat, 27 Jul 2019 19:32:29 -0400 Received: by mail-wr1-f65.google.com with SMTP id f9so57925381wre.12 for <35564@debbugs.gnu.org>; Sat, 27 Jul 2019 16:32:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=nAA/Ln4pkw1b+xQEdR2SRFjwKo9QRWMzs/vt2eVrcLk=; b=QPmIFij0Du3dyqw+RPxCn5VtjEdjo6tUibkHw72R1j9YVSx8UYOgjXiD7+mP/L17iV PHw0TByXkoSabcnOLKoEtse1VDDNVhej5pASs/j1PJdrJhK3SXq6mTW5SQWhSTSetEWH dOT25fwAIKwOkmDPOsuT7l9H5OWBRalI0VAAnjq/68RYjD6EXgZpC6D244bQbdfhwmxC f3BDyBwbXT1s/GqyrZ7fITyTo+ZJX9p4hThBu/CDNKQh9RbeGjUXDah1YEZZimXuMbJn kX0YbRYDyGUjCZDtgAWAom+Mspp4CetCuRRAja4GFCHyuOt6Bw30i9h3SHQZQNub5hOH NtzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=nAA/Ln4pkw1b+xQEdR2SRFjwKo9QRWMzs/vt2eVrcLk=; b=SUS4LoTCfK8FCi0xdTpP/AzZRISgKRXTVXNV789Zb0iSfp3dzIIySqRxpMAvlCT54i M3SpEmXlhpKL27HjKOKRslzpAN5D874PYnmwCn9uemTLtuj5Vgv4fQphC8O1BEZUEvzU 6OYhE1xvEOE5/BOSOxrqvxkLD0h1tEDpkfQJ2SKl+IFJSJJ7nvmha6klBRIdGBRokenp uShmeDPS4sChjDJP6rJ3SvOap3emvrH9yy/1ubL4WzVVxSM75Htg1sxJzdpDIB0R0lBF WZBMsp1YxSGrFK+uWKlY1zDxwgQc73u1jxxXR29DDunUBO7O8Qp8ECwWxbt6ev3xaXP+ NGqw== X-Gm-Message-State: APjAAAXbK3xNSAb5PJfT0F7ghdSqdPd7gz0WW1iFlQmr5GfCJ2mfY9f+ rHboV5ghnRDRMAH7F2NVs8s= X-Google-Smtp-Source: APXvYqy5hyEwsNrPLijfnKxSPDWYchpFu91TWsSjMNmP4lwbUeaBi28o6CFv/PVjd6DdLHx6kl4CmA== X-Received: by 2002:adf:ce07:: with SMTP id p7mr30250649wrn.129.1564270341780; Sat, 27 Jul 2019 16:32:21 -0700 (PDT) Received: from nc10-laptop (2a01cb04010fc800c8771fb97d0446e3.ipv6.abo.wanadoo.fr. [2a01:cb04:10f:c800:c877:1fb9:7d04:46e3]) by smtp.gmail.com with ESMTPSA id b15sm72882550wrt.77.2019.07.27.16.32.20 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 27 Jul 2019 16:32:20 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: "Basil L. Contovounesios" Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> <87imrn16fk.fsf@tcd.ie> Date: Sun, 28 Jul 2019 01:32:19 +0200 In-Reply-To: <87imrn16fk.fsf@tcd.ie> (Basil L. Contovounesios's message of "Sat, 27 Jul 2019 23:03:27 +0100") Message-ID: <87lfwjoxz0.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Eli Zaretskii , 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable "Basil L. Contovounesios" writes: >> -(defun dired--no-subst-prompt (char-positions command) >> +(defun dired--mark-positions (positions) >> + (let ((markers (make-string >> + (1+ (apply #'max positions)) > > Is POSITIONS guaranteed to be non-nil? (The max function takes at least > one argument.) AFAICT dired--mark-positions is only called by dired--no-subst-prompt, which is only used when there is at least one ambiguous character to highlight. So as things stand now, POSITIONS will always be non-nil. Nothing prevents someone from attempting to re-use the function with a potentially-nil argument though. I don't know what makes more sense here: adding an assertion? Handling the nil case explicitly for robustness? >> Subject: [PATCH 6/6] Simplify highlighting assertions >> >> * test/lisp/dired-aux-tests.el (dired-test--check-highlighting): >> New function. >> (dired-test-highlight-metachar): Use it. > > Will this simplification hinder debugging of test failures? I don't > have an opinion on the proposed change, it's just something to consider. Mmm. Since the assertion that fails is now nested in a more generic function, the report shown in the ERT-Results buffer might be somewhat less informative; one has to bring up the backtrace to understand the context. I could try my hand at an ERT explainer for these assertions. Or we could just drop the 6th patch=E2=80=A6 I do find the tests easier to read = and write with it though. PS: Looking at this made me realize that patch #5 was borked (missed a parenthesis in dired-test-highlight-metachar, so the tests just plain wouldn't run). Here is the patch series with patches #5 and #6 fixed. The squashed patch[1] remains the same. --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Preserve-text-properties-in-y-or-n-p-prompts.patch >From f8f22404a6e0a46cd27149491df781d8c2c4cea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:03:59 +0200 Subject: [PATCH 1/6] Preserve text properties in y-or-n-p prompts * lisp/subr.el (read--propertize-prompt): New function to append the prompt face to a string. (y-or-n-p): Use it instead of discarding potential text properties. (Bug#35564) --- lisp/subr.el | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lisp/subr.el b/lisp/subr.el index eea4e045dd..0766530239 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2343,6 +2343,9 @@ memory-limit ;;;; Input and display facilities. +(defun read--propertize-prompt (prompt) + (add-face-text-property 0 (length prompt) 'minibuffer-prompt t prompt)) + (defconst read-key-empty-map (make-sparse-keymap)) (defvar read-key-delay 0.01) ;Fast enough for 100Hz repeat rate, hopefully. @@ -2680,14 +2683,14 @@ y-or-n-p (let* ((scroll-actions '(recenter scroll-up scroll-down scroll-other-window scroll-other-window-down)) (key - (let ((cursor-in-echo-area t)) + (let ((cursor-in-echo-area t) + (prompt (if (memq answer scroll-actions) + prompt + (concat "Please answer y or n. " prompt)))) (when minibuffer-auto-raise (raise-frame (window-frame (minibuffer-window)))) - (read-key (propertize (if (memq answer scroll-actions) - prompt - (concat "Please answer y or n. " - prompt)) - 'face 'minibuffer-prompt))))) + (read--propertize-prompt prompt) + (read-key prompt)))) (setq answer (lookup-key query-replace-map (vector key) t)) (cond ((memq answer '(skip act)) nil) -- 2.20.1 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0002-Tweak-dired-warning-about-wildcard-characters.patch >From 047a2d355cbd167d93a1bbd25de64e2fb16fd815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:19:44 +0200 Subject: [PATCH 2/6] Tweak dired warning about "wildcard" characters Non-isolated '?' and '*' characters may be quoted, or backslash-escaped; we do not know for a fact that the shell will interpret them as wildcards. Rephrase the prompt and highlight the characters so that the user sees exactly what we are talking about. * lisp/dired-aux.el (dired--isolated-char-p) (dired--highlight-nosubst-char, dired--no-subst-prompt): New functions. (dired-do-shell-command): Use them. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p) (dired-test-highlight-metachar): Test the new functions. (Bug#35564) --- lisp/dired-aux.el | 42 ++++++++++++++++++++++++++++++++---- test/lisp/dired-aux-tests.el | 28 ++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 30a941c7bb..1e1ebf7552 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -79,6 +79,42 @@ dired--star-or-qmark-p (funcall (if keep #'string-match-p #'string-match) x string)) regexps))) +(defun dired--isolated-char-p (command pos) + "Assert whether the character at POS is isolated within COMMAND. +A character is isolated if: +- it is surrounded by whitespace, the start of the command, or + the end of the command, +- it is surrounded by `\\=`' characters." + (let ((start (max 0 (1- pos))) + (char (string (aref command pos)))) + (and (string-match + (rx (or (seq (or bos blank) + (group-n 1 (literal char)) + (or eos blank)) + (seq ?` (group-n 1 (literal char)) ?`))) + command start) + (= pos (match-beginning 1))))) + +(defun dired--highlight-nosubst-char (command char) + "Highlight occurences of CHAR that are not isolated in COMMAND. +These occurences will not be substituted; they will be sent as-is +to the shell, which may interpret them as wildcards." + (save-match-data + (let ((highlighted (substring-no-properties command)) + (pos 0)) + (while (string-match (regexp-quote char) command pos) + (let ((start (match-beginning 0)) + (end (match-end 0))) + (unless (dired--isolated-char-p command start) + (add-face-text-property start end 'warning nil highlighted)) + (setq pos end))) + highlighted))) + +(defun dired--no-subst-prompt (command char) + (let ((highlighted-command (dired--highlight-nosubst-char command char)) + (prompt "Confirm--the highlighted characters will not be substituted:")) + (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + ;;;###autoload (defun dired-diff (file &optional switches) "Compare file at point with FILE using `diff'. @@ -761,11 +797,9 @@ dired-do-shell-command (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((need-confirm-p command "*") - (y-or-n-p (format-message - "Confirm--do you mean to use `*' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "*"))) ((need-confirm-p command "?") - (y-or-n-p (format-message - "Confirm--do you mean to use `?' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "?"))) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ccd3192792..80b6393931 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,6 +114,34 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(ert-deftest dired-test-isolated-char-p () + (should (dired--isolated-char-p "?" 0)) + (should (dired--isolated-char-p "? " 0)) + (should (dired--isolated-char-p " ?" 1)) + (should (dired--isolated-char-p " ? " 1)) + (should (dired--isolated-char-p "foo bar ? baz" 8)) + (should (dired--isolated-char-p "foo -i`?`" 7)) + (should-not (dired--isolated-char-p "foo `bar`?" 9)) + (should-not (dired--isolated-char-p "foo 'bar?'" 8)) + (should-not (dired--isolated-char-p "foo bar?baz" 7)) + (should-not (dired--isolated-char-p "foo bar?" 7))) + +(ert-deftest dired-test-highlight-metachar () + "Check that non-isolated meta-characters are highlighted" + (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (result (dired--highlight-nosubst-char command "?"))) + (should-not (text-property-not-all 1 14 'face nil result)) + (should (equal 'warning (get-text-property 15 'face result))) + (should-not (text-property-not-all 16 28 'face nil result)) + (should (equal 'warning (get-text-property 29 'face result))) + (should-not (text-property-not-all 30 39 'face nil result))) + (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") + (result (dired--highlight-nosubst-char command "*"))) + (should-not (text-property-not-all 1 10 'face nil result)) + (should (equal 'warning (get-text-property 11 'face result))) + (should-not (text-property-not-all 12 23 'face nil result)) + (should (equal 'warning (get-text-property 24 'face result))) + (should-not (text-property-not-all 25 29 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.20.1 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0003-Dedup-dired-aux-isolated-char-searching-Bug-35564.patch >From 83497dc721d098ba089589ec2a5987a3b986c807 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 27 Jun 2019 19:15:56 -0400 Subject: [PATCH 3/6] Dedup dired-aux isolated char searching (Bug#35564) * lisp/dired-aux.el (dired-isolated-string-re): Use explicitly numbered groups. (dired--star-or-qmark-p): Add START parameter. Make sure to return the first isolated match. (dired--no-subst-prompt): Operate on a list of positions rather than searching again for isolated chars. Shorten prompt, and include the character being asked about in the question (to make it clearer, and in case the user can't see the fontification for whatever reason, e.g., screen reader). (dired--isolated-char-p): Remove. (dired--need-confirm-positions): New function. (dired-do-shell-command): Use it. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p): Remove. (dired-test-highlight-metachar): Adjust to new functions. Make sure that `*` isn't considered isolated. --- lisp/dired-aux.el | 113 ++++++++++++++++------------------- test/lisp/dired-aux-tests.el | 31 +++++----- 2 files changed, 67 insertions(+), 77 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 1e1ebf7552..ca5b8cf801 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -60,60 +60,60 @@ dired-isolated-string-re of a string followed/prefixed with an space. The regexp capture the preceding blank, STRING and the following blank as the groups 1, 2 and 3 respectively." - (format "\\(\\`\\|[ \t]\\)\\(%s\\)\\([ \t]\\|\\'\\)" string)) + (format "\\(?1:\\`\\|[ \t]\\)\\(?2:%s\\)\\(?3:[ \t]\\|\\'\\)" string)) -(defun dired--star-or-qmark-p (string match &optional keep) +(defun dired--star-or-qmark-p (string match &optional keep start) "Return non-nil if STRING contains isolated MATCH or `\\=`?\\=`'. MATCH should be the strings \"?\", `\\=`?\\=`', \"*\" or nil. The latter means STRING contains either \"?\" or `\\=`?\\=`' or \"*\". If optional arg KEEP is non-nil, then preserve the match data. Otherwise, this function changes it and saves MATCH as the second match group. +START is the position to start matching from. Isolated means that MATCH is surrounded by spaces or at the beginning/end of STRING followed/prefixed with an space. A match to `\\=`?\\=`', isolated or not, is also valid." - (let ((regexps (list (dired-isolated-string-re (if match (regexp-quote match) "[*?]"))))) + (let ((regexp (dired-isolated-string-re (if match (regexp-quote match) "[*?]")))) (when (or (null match) (equal match "?")) - (setq regexps (append (list "\\(\\)\\(`\\?`\\)\\(\\)") regexps))) - (cl-some (lambda (x) - (funcall (if keep #'string-match-p #'string-match) x string)) - regexps))) - -(defun dired--isolated-char-p (command pos) - "Assert whether the character at POS is isolated within COMMAND. -A character is isolated if: -- it is surrounded by whitespace, the start of the command, or - the end of the command, -- it is surrounded by `\\=`' characters." - (let ((start (max 0 (1- pos))) - (char (string (aref command pos)))) - (and (string-match - (rx (or (seq (or bos blank) - (group-n 1 (literal char)) - (or eos blank)) - (seq ?` (group-n 1 (literal char)) ?`))) - command start) - (= pos (match-beginning 1))))) - -(defun dired--highlight-nosubst-char (command char) - "Highlight occurences of CHAR that are not isolated in COMMAND. -These occurences will not be substituted; they will be sent as-is -to the shell, which may interpret them as wildcards." - (save-match-data - (let ((highlighted (substring-no-properties command)) - (pos 0)) - (while (string-match (regexp-quote char) command pos) - (let ((start (match-beginning 0)) - (end (match-end 0))) - (unless (dired--isolated-char-p command start) - (add-face-text-property start end 'warning nil highlighted)) - (setq pos end))) - highlighted))) - -(defun dired--no-subst-prompt (command char) - (let ((highlighted-command (dired--highlight-nosubst-char command char)) - (prompt "Confirm--the highlighted characters will not be substituted:")) - (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + (cl-callf concat regexp "\\|\\(?1:\\)\\(?2:`\\?`\\)\\(?3:\\)")) + (funcall (if keep #'string-match-p #'string-match) regexp string start))) + +(defun dired--need-confirm-positions (command string) + "Search for non-isolated matches of STRING in COMMAND. +Return a list of positions that match STRING, but would not be +considered \"isolated\" by `dired--star-or-qmark-p'." + (cl-assert (= (length string) 1)) + (let ((start 0) + (isolated-char-positions nil) + (confirm-positions nil) + (regexp (regexp-quote string))) + ;; Collect all ? and * surrounded by spaces and `?`. + (while (dired--star-or-qmark-p command string nil start) + (push (cons (match-beginning 2) (match-end 2)) + isolated-char-positions) + (setq start (match-end 2))) + ;; Now collect any remaining ? and *. + (setq start 0) + (while (string-match regexp command start) + (unless (cl-member (match-beginning 0) isolated-char-positions + :test (lambda (pos match) + (<= (car match) pos (cdr match)))) + (push (match-beginning 0) confirm-positions)) + (setq start (match-end 0))) + confirm-positions)) + +(defun dired--no-subst-prompt (char-positions command) + (cl-callf substring-no-properties command) + (dolist (pos char-positions) + (add-face-text-property pos (1+ pos) 'warning nil command)) + (concat command "\n" + (format-message + (ngettext "Send %d occurence of `%s' as-is to shell?" + "Send %d occurences of `%s' as-is to shell?" + (length char-positions)) + (length char-positions) + (propertize (string (aref command (car char-positions))) + 'face 'warning)))) ;;;###autoload (defun dired-diff (file &optional switches) @@ -781,26 +781,19 @@ dired-do-shell-command (dired-read-shell-command "! on %s: " current-prefix-arg files) current-prefix-arg files))) - (cl-flet ((need-confirm-p - (cmd str) - (let ((res cmd) - (regexp (regexp-quote str))) - ;; Drop all ? and * surrounded by spaces and `?`. - (while (and (string-match regexp res) - (dired--star-or-qmark-p res str)) - (setq res (replace-match "" t t res 2))) - (string-match regexp res)))) (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) + (confirmations nil) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. - (ok (cond ((not (or on-each no-subst)) - (error "You can not combine `*' and `?' substitution marks")) - ((need-confirm-p command "*") - (y-or-n-p (dired--no-subst-prompt command "*"))) - ((need-confirm-p command "?") - (y-or-n-p (dired--no-subst-prompt command "?"))) - (t)))) + (ok (cond + ((not (or on-each no-subst)) + (error "You can not combine `*' and `?' substitution marks")) + ((setq confirmations (dired--need-confirm-positions command "*")) + (y-or-n-p (dired--no-subst-prompt confirmations command))) + ((setq confirmations (dired--need-confirm-positions command "?")) + (y-or-n-p (dired--no-subst-prompt confirmations command))) + (t)))) (cond ((not ok) (message "Command canceled")) (t (if on-each @@ -811,7 +804,7 @@ dired-do-shell-command nil file-list) ;; execute the shell command (dired-run-shell-command - (dired-shell-stuff-it command file-list nil arg)))))))) + (dired-shell-stuff-it command file-list nil arg))))))) ;; Might use {,} for bash or csh: (defvar dired-mark-prefix "" diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 80b6393931..3f4bfffaf6 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,34 +114,31 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) -(ert-deftest dired-test-isolated-char-p () - (should (dired--isolated-char-p "?" 0)) - (should (dired--isolated-char-p "? " 0)) - (should (dired--isolated-char-p " ?" 1)) - (should (dired--isolated-char-p " ? " 1)) - (should (dired--isolated-char-p "foo bar ? baz" 8)) - (should (dired--isolated-char-p "foo -i`?`" 7)) - (should-not (dired--isolated-char-p "foo `bar`?" 9)) - (should-not (dired--isolated-char-p "foo 'bar?'" 8)) - (should-not (dired--isolated-char-p "foo bar?baz" 7)) - (should-not (dired--isolated-char-p "foo bar?" 7))) - (ert-deftest dired-test-highlight-metachar () "Check that non-isolated meta-characters are highlighted" (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") - (result (dired--highlight-nosubst-char command "?"))) + (prompt (dired--no-subst-prompt + command + (dired--need-confirm-positions command "?"))) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 14 'face nil result)) (should (equal 'warning (get-text-property 15 'face result))) (should-not (text-property-not-all 16 28 'face nil result)) (should (equal 'warning (get-text-property 29 'face result))) (should-not (text-property-not-all 30 39 'face nil result))) - (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") - (result (dired--highlight-nosubst-char command "*"))) + ;; Note that `?` is considered isolated, but `*` is not. + (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (prompt (dired--no-subst-prompt + command + (dired--need-confirm-positions command "*"))) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 10 'face nil result)) (should (equal 'warning (get-text-property 11 'face result))) (should-not (text-property-not-all 12 23 'face nil result)) - (should (equal 'warning (get-text-property 24 'face result))) - (should-not (text-property-not-all 25 29 'face nil result)))) + (should (equal 'warning (get-text-property 25 'face result))) + (should-not (text-property-not-all 26 32 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.20.1 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0004-fixup-Dedup-dired-aux-isolated-char-searching-Bug-35.patch >From 612e77f1cd0163c383a20b4401bfcf5e299b0aa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 3 Jul 2019 21:29:38 +0200 Subject: [PATCH 4/6] fixup! Dedup dired-aux isolated char searching (Bug#35564) --- lisp/dired-aux.el | 4 ++-- test/lisp/dired-aux-tests.el | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index ca5b8cf801..b15a9426dc 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -108,8 +108,8 @@ dired--no-subst-prompt (add-face-text-property pos (1+ pos) 'warning nil command)) (concat command "\n" (format-message - (ngettext "Send %d occurence of `%s' as-is to shell?" - "Send %d occurences of `%s' as-is to shell?" + (ngettext "Send %d occurrence of `%s' as-is to shell?" + "Send %d occurrences of `%s' as-is to shell?" (length char-positions)) (length char-positions) (propertize (string (aref command (car char-positions))) diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 3f4bfffaf6..ff18edddb6 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -118,8 +118,8 @@ dired-test-highlight-metachar "Check that non-isolated meta-characters are highlighted" (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") (prompt (dired--no-subst-prompt - command - (dired--need-confirm-positions command "?"))) + (dired--need-confirm-positions command "?") + command)) (result (and (string-match (regexp-quote command) prompt) (match-string 0 prompt)))) (should-not (text-property-not-all 1 14 'face nil result)) @@ -130,8 +130,8 @@ dired-test-highlight-metachar ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") (prompt (dired--no-subst-prompt - command - (dired--need-confirm-positions command "*"))) + (dired--need-confirm-positions command "*") + command)) (result (and (string-match (regexp-quote command) prompt) (match-string 0 prompt)))) (should-not (text-property-not-all 1 10 'face nil result)) -- 2.20.1 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0005-Add-markers-below-non-isolated-chars-in-dired-prompt.patch >From 9ba62e66fcdbba8305821acf690f263e9ccf10a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 3 Jul 2019 21:17:57 +0200 Subject: [PATCH 5/6] Add '^' markers below non-isolated chars in dired prompt * lisp/dired-aux.el (dired--mark-positions): New function. (dired--no-subst-prompt): Use it to show chars without overly relying on highlighting. (dired-do-shell-command): When the echo area is wide enough to display the command without wrapping it, add the markers. * test/lisp/dired-aux-tests.el (dired-test-highlight-metachar): Add assertion for '^' marker positions. (Bug#35564) --- lisp/dired-aux.el | 43 +++++++++++++++++++++-------- test/lisp/dired-aux-tests.el | 53 ++++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 28 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index b15a9426dc..3887d75356 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -102,18 +102,35 @@ dired--need-confirm-positions (setq start (match-end 0))) confirm-positions)) -(defun dired--no-subst-prompt (char-positions command) +(defun dired--mark-positions (positions) + (let ((markers (make-string + (1+ (apply #'max positions)) + ?\s))) + (dolist (pos positions) + (setf (aref markers pos) ?^)) + markers)) + +(defun dired--no-subst-prompt (char-positions command add-markers) (cl-callf substring-no-properties command) (dolist (pos char-positions) (add-face-text-property pos (1+ pos) 'warning nil command)) - (concat command "\n" - (format-message - (ngettext "Send %d occurrence of `%s' as-is to shell?" - "Send %d occurrences of `%s' as-is to shell?" - (length char-positions)) - (length char-positions) - (propertize (string (aref command (car char-positions))) - 'face 'warning)))) + ;; `y-or-n-p' adds some text to the beginning of the prompt when the + ;; user fails to answer 'y' or 'n'. The highlighted command thus + ;; cannot be put on the first line of the prompt, since the added + ;; text will shove the command to the right, and the '^' markers + ;; will become misaligned. + (apply #'concat + `("Confirm:\n" + ,command "\n" + ,@(when add-markers + (list (dired--mark-positions char-positions) "\n")) + ,(format-message + (ngettext "Send %d occurrence of `%s' as-is to shell?" + "Send %d occurrences of `%s' as-is to shell?" + (length char-positions)) + (length char-positions) + (propertize (string (aref command (car char-positions))) + 'face 'warning))))) ;;;###autoload (defun dired-diff (file &optional switches) @@ -784,15 +801,19 @@ dired-do-shell-command (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) (confirmations nil) + (short-enough (< (length command) + (window-width (minibuffer-window)))) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((setq confirmations (dired--need-confirm-positions command "*")) - (y-or-n-p (dired--no-subst-prompt confirmations command))) + (y-or-n-p (dired--no-subst-prompt confirmations command + short-enough))) ((setq confirmations (dired--need-confirm-positions command "?")) - (y-or-n-p (dired--no-subst-prompt confirmations command))) + (y-or-n-p (dired--no-subst-prompt confirmations command + short-enough))) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ff18edddb6..174c27052e 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -115,30 +115,49 @@ dired-test-bug30624 (kill-buffer buf))))) (ert-deftest dired-test-highlight-metachar () - "Check that non-isolated meta-characters are highlighted" + "Check that non-isolated meta-characters are highlighted." (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (markers " ^ ^") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "?") - command)) - (result (and (string-match (regexp-quote command) prompt) - (match-string 0 prompt)))) - (should-not (text-property-not-all 1 14 'face nil result)) - (should (equal 'warning (get-text-property 15 'face result))) - (should-not (text-property-not-all 16 28 'face nil result)) - (should (equal 'warning (get-text-property 29 'face result))) - (should-not (text-property-not-all 30 39 'face nil result))) + command + t)) + (lines (split-string prompt "\n")) + (highlit-command (nth 1 lines))) + (should (= (length lines) 4)) + (should (string-match (regexp-quote command) highlit-command)) + (should (string-match (regexp-quote markers) (nth 2 lines))) + (should-not (text-property-not-all 1 14 'face nil highlit-command)) + (should (equal 'warning (get-text-property 15 'face highlit-command))) + (should-not (text-property-not-all 16 28 'face nil highlit-command)) + (should (equal 'warning (get-text-property 29 'face highlit-command))) + (should-not (text-property-not-all 30 39 'face nil highlit-command))) ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (markers " ^ ^") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "*") - command)) - (result (and (string-match (regexp-quote command) prompt) - (match-string 0 prompt)))) - (should-not (text-property-not-all 1 10 'face nil result)) - (should (equal 'warning (get-text-property 11 'face result))) - (should-not (text-property-not-all 12 23 'face nil result)) - (should (equal 'warning (get-text-property 25 'face result))) - (should-not (text-property-not-all 26 32 'face nil result)))) + command + t)) + (lines (split-string prompt "\n")) + (highlit-command (nth 1 lines))) + (should (= (length lines) 4)) + (should (string-match (regexp-quote command) highlit-command)) + (should (string-match (regexp-quote markers) (nth 2 lines))) + (should-not (text-property-not-all 1 10 'face nil highlit-command)) + (should (equal 'warning (get-text-property 11 'face highlit-command))) + (should-not (text-property-not-all 12 23 'face nil highlit-command)) + (should (equal 'warning (get-text-property 25 'face highlit-command))) + (should-not (text-property-not-all 26 32 'face nil highlit-command))) + (let* ((command "sed 's/\\?/!/'") + (prompt (dired--no-subst-prompt + (dired--need-confirm-positions command "?") + command + nil)) + (lines (split-string prompt "\n")) + (highlit-command (nth 1 lines))) + (should (= (length lines) 3)) + (should (string-match (regexp-quote command) highlit-command)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.20.1 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0006-Simplify-highlighting-assertions.patch >From c5729141cda2131a4c72f268bfacf36b6ebca47c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 12 Jul 2019 16:10:54 +0200 Subject: [PATCH 6/6] Simplify highlighting assertions * test/lisp/dired-aux-tests.el (dired-test--check-highlighting): New function. (dired-test-highlight-metachar): Use it. (Bug#35564) --- test/lisp/dired-aux-tests.el | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 174c27052e..ba10c54332 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,6 +114,15 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(defun dired-test--check-highlighting (command positions) + (let ((start 1)) + (dolist (pos positions) + (should-not (text-property-not-all start (1- pos) 'face nil command)) + (should (equal 'warning (get-text-property pos 'face command))) + (setq start (1+ pos))) + (should-not (text-property-not-all + start (length command) 'face nil command)))) + (ert-deftest dired-test-highlight-metachar () "Check that non-isolated meta-characters are highlighted." (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") @@ -127,11 +136,7 @@ dired-test-highlight-metachar (should (= (length lines) 4)) (should (string-match (regexp-quote command) highlit-command)) (should (string-match (regexp-quote markers) (nth 2 lines))) - (should-not (text-property-not-all 1 14 'face nil highlit-command)) - (should (equal 'warning (get-text-property 15 'face highlit-command))) - (should-not (text-property-not-all 16 28 'face nil highlit-command)) - (should (equal 'warning (get-text-property 29 'face highlit-command))) - (should-not (text-property-not-all 30 39 'face nil highlit-command))) + (dired-test--check-highlighting highlit-command '(15 29))) ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") (markers " ^ ^") @@ -144,11 +149,7 @@ dired-test-highlight-metachar (should (= (length lines) 4)) (should (string-match (regexp-quote command) highlit-command)) (should (string-match (regexp-quote markers) (nth 2 lines))) - (should-not (text-property-not-all 1 10 'face nil highlit-command)) - (should (equal 'warning (get-text-property 11 'face highlit-command))) - (should-not (text-property-not-all 12 23 'face nil highlit-command)) - (should (equal 'warning (get-text-property 25 'face highlit-command))) - (should-not (text-property-not-all 26 32 'face nil highlit-command))) + (dired-test--check-highlighting highlit-command '(11 25))) (let* ((command "sed 's/\\?/!/'") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "?") @@ -157,7 +158,8 @@ dired-test-highlight-metachar (lines (split-string prompt "\n")) (highlit-command (nth 1 lines))) (should (= (length lines) 3)) - (should (string-match (regexp-quote command) highlit-command)))) + (should (string-match (regexp-quote command) highlit-command)) + (dired-test--check-highlighting highlit-command '(8)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.20.1 --=-=-= Content-Type: text/plain Thank you for your review. [1] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=28969#19 --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sat Jul 27 19:41:31 2019 Received: (at 35564) by debbugs.gnu.org; 27 Jul 2019 23:41:31 +0000 Received: from localhost ([127.0.0.1]:45581 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrWJe-0004pJ-My for submit@debbugs.gnu.org; Sat, 27 Jul 2019 19:41:30 -0400 Received: from mail-wr1-f54.google.com ([209.85.221.54]:45558) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrWJc-0004p5-Mb for 35564@debbugs.gnu.org; Sat, 27 Jul 2019 19:41:29 -0400 Received: by mail-wr1-f54.google.com with SMTP id f9so57934084wre.12 for <35564@debbugs.gnu.org>; Sat, 27 Jul 2019 16:41:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tcd-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=+RuokGQqKBuczS8oAuLoeh0S552zO0prvh0UPL8YF1Y=; b=b0Pp4v2+nc7N/ybfT6lmwv6Nnc5WuCF9waGBqQstTrV84KJfF4/H/n6Ir2ZsM0Kjms u348jQgSlpIR5v+thWrTuft4ClbvP+ciedN9vKcf22XiwILS3oexj2CClcONZDATzHsZ AsWPs2va3CXbf940a1Rjf9TsQR2XcX5Q4DZVe1OEJGmQ6avDmD9XIda7cCrZy9Hp+ToM fh9MzXkr37Zcu/KIfJXDpqz41FGUsUftDa8xOE3C9gG9bGhFlRGRdfkD67wS+OpBmTPx n5gvD8lOQ4/ABjMJk+WHrpOz3rmQdVWdKa5vcpslWD9HyUxURFDWiZHhpLtKdfWXtdAt N6zA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=+RuokGQqKBuczS8oAuLoeh0S552zO0prvh0UPL8YF1Y=; b=SS3dbfe6aH+qqdcQQozUneJnWnAA53UD2qalG3aY7eZ15ZyJqzfr7Bt1n0mH9qlqs4 YuxIpDMyL0/K5vwreuQPr7XHM3JAJ0XMBDLdbTOInsupBthnXiG1NP8MCBWodaFJX1B2 ilUCbHOFOftWBWtDbUGe8S5V55T3zxgIhOuOODMUk5HsspeVA968EfelhlMNhW0KeeVw CA1W1qXVlKwq984yMsE7DmOhRZikOzKjfdxixXQv8pxMa1uSoSRUkeijDYkjkCPxZUkF HmwhH53ny4Y7Jt1Mhjz6WW6knK/ta+v5wfYd0BttWFw2mE+h2ze5ygE5tfNEYwCROIyu q5Fg== X-Gm-Message-State: APjAAAXntiLVNjYLqW9Q6Sx5uaMMamMsNITQ6bCM3EW9+3qHnmAALiVO bKdva8SgFNFHET9RINsNPzTvrQ== X-Google-Smtp-Source: APXvYqxw9klneHIJeOJmzOunHWL2RwL9y3LhiNI1/hstKH6MDsOTsuSJAXRgfYSiHJ5QorR16p7MJw== X-Received: by 2002:a5d:4d81:: with SMTP id b1mr27984324wru.27.1564270882725; Sat, 27 Jul 2019 16:41:22 -0700 (PDT) Received: from localhost ([2a02:8084:20e2:c380:92bd:1bfd:38fc:fae2]) by smtp.gmail.com with ESMTPSA id z6sm51050746wrw.2.2019.07.27.16.41.21 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Sat, 27 Jul 2019 16:41:21 -0700 (PDT) From: "Basil L. Contovounesios" To: =?utf-8?Q?K=C3=A9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> <87imrn16fk.fsf@tcd.ie> <87lfwjoxz0.fsf@gmail.com> Date: Sun, 28 Jul 2019 00:41:20 +0100 In-Reply-To: <87lfwjoxz0.fsf@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Sun, 28 Jul 2019 01:32:19 +0200") Message-ID: <87d0hvyrj3.fsf@tcd.ie> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Eli Zaretskii , 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) K=C3=A9vin Le Gouguec writes: > "Basil L. Contovounesios" writes: > >>> -(defun dired--no-subst-prompt (char-positions command) >>> +(defun dired--mark-positions (positions) >>> + (let ((markers (make-string >>> + (1+ (apply #'max positions)) >> >> Is POSITIONS guaranteed to be non-nil? (The max function takes at least >> one argument.) > > AFAICT dired--mark-positions is only called by dired--no-subst-prompt, > which is only used when there is at least one ambiguous character to > highlight. > > So as things stand now, POSITIONS will always be non-nil. Nothing > prevents someone from attempting to re-use the function with a > potentially-nil argument though. > > I don't know what makes more sense here: adding an assertion? Handling > the nil case explicitly for robustness? I think it's fine the way it is, though a docstring/comment never hurts. I was just checking. >>> Subject: [PATCH 6/6] Simplify highlighting assertions >>> >>> * test/lisp/dired-aux-tests.el (dired-test--check-highlighting): >>> New function. >>> (dired-test-highlight-metachar): Use it. >> >> Will this simplification hinder debugging of test failures? I don't >> have an opinion on the proposed change, it's just something to consider. > > Mmm. Since the assertion that fails is now nested in a more generic > function, the report shown in the ERT-Results buffer might be somewhat > less informative; one has to bring up the backtrace to understand the > context. > > I could try my hand at an ERT explainer for these assertions. Or we > could just drop the 6th patch=E2=80=A6 I do find the tests easier to rea= d and > write with it though. That's good enough for me, --=20 Basil From debbugs-submit-bounces@debbugs.gnu.org Sun Jul 28 23:30:00 2019 Received: (at 35564) by debbugs.gnu.org; 29 Jul 2019 03:30:00 +0000 Received: from localhost ([127.0.0.1]:47477 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrwMJ-0006FR-Ou for submit@debbugs.gnu.org; Sun, 28 Jul 2019 23:29:59 -0400 Received: from mout.web.de ([212.227.17.11]:55343) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hrwMG-0006FC-QD for 35564@debbugs.gnu.org; Sun, 28 Jul 2019 23:29:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1564370981; bh=SPVkCy49K7oMfnlinj+7Ca19xdHQFoy01OkNL2i2HU8=; h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To; b=LXb2DCCmPaA0vlw053TGIbEYY0fbXtxTCNAwJ1mtunWSM4b0PxfX1/bUezS+v/VUi bjO6O9EeizEKPKFlBKHLoa7ElRFfj8VnYyRz57hP/j486xk3Tri/he700X/fd9cGIU z1DhrvkaYum17xoskOUw9GXeajEnZovtJclJV42Q= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from drachen.dragon ([92.208.178.242]) by smtp.web.de (mrweb103 [213.165.67.124]) with ESMTPSA (Nemesis) id 0M09hY-1ifVCj00mi-00uIS2; Mon, 29 Jul 2019 05:29:41 +0200 From: Michael Heerdegen To: =?utf-8?Q?K=C3=A9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> <87wog3pewu.fsf@gmail.com> <87v9vndsnj.fsf@web.de> Date: Mon, 29 Jul 2019 05:29:36 +0200 In-Reply-To: <87v9vndsnj.fsf@web.de> (Michael Heerdegen's message of "Sun, 28 Jul 2019 00:22:40 +0200") Message-ID: <87imrl4ixr.fsf@web.de> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Provags-ID: V03:K1:NoVetfnANGCJgVzgWU5tmJuLZvTK+VJzIM883UCKzRIVejUBuoW MlOs8ntXRD+S/V63AuoKYfNXNsHhZ3lVw95UxMwnwJ8i/JJhhedEAeDZl2nFYwuU9O2luDJ L+VRtyPA0hsQWc5Wt1BzmrPrsMVLKy63k8+xMODrWte1BRPqVp56A3/mDtPVJAkwmf25Oa8 jjUgzHeJ7vqvyb6INMajg== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:ZWHdeNXsoF0=:6rbaJOEZKDd6fwHgJyAjg5 k7g22wUnBdjz9Md4c5mtDXC6DNSrGfaqK9wn6yxdMP977QqBDjjtZYhauY/P0FyoE+Tqh5GYU mRB+07NeJO1qB+TZ+jWWI+MkelR9MGninjEHPHRhraLkC8J62P41I+SE5f2ttnXYx4yofXw3Z wBjjsoS8dJ0xB4jly0EftyAz/8gl4F80zyPDMLet1IZ24Ws4EQUsl9+5Lk7SLU6zWpZcDmYol iX4Md7HeGKYcUQJNzHOwGVnFfUoCMBQx01GLG13VcbRei8wgANNusZS1PhcGKiH2NSr+0eOYC HVvVlgczACHAsPk/Mt+g7AxbaKO9cOVpTBhhEX6/qCMxXjqbZ51kuP/5obnbOH+roxxrEWWfr 6UsLeqCrx8NpbOw52UzgoFIownv/6k3CiTUK+ZUuYKFZ9W7VpfKoLb+cNyNGVcWHPS27Lia4Q fD2I8efopgGasH7CE5wYUuaiaboEPkryVrTGpFQYb0ue07EEBtqxt25X8vtfpY9pgy8YISUbm EmJLi6PTfV7zcaNkPMkZ7mS5upNiUY7ATh5isIEiV8gXsvdeE/X1dGIeTR+xAtSvdbukR667N 9WuqSL23yerIioWFWot/ac825CMT65euwBjR3IqIpoiO4gPd37wKgNUihh3oCpxjVftCxFvtU JmA/qeXMtrPkSlGhlkkQs7KAZ6c7jKhFcSHAmOg4VwG56qcnWMjduT7oCtGG8o0H4uGV7drDp ls6PnyUjbXRWnQkwC1a3PZB/yBx0fXjvkz1RU3hJWSThKmeRd6Xc7rt78BZsdt1CxzI5DgFbi RblIx0AmP9afsteLPnC3u/mhBmLz6Z1tHNWh5y/QK9rNwXraNgkuL1k5CV7yKL7XrA7kJdzH8 OamU/YA9F7vjvmNBx/FNOXcz0Ig/8DMp26NepR606qyHJhRhOgNTwleOD3EeUS2BwFO/NhPD+ lIQgV2S69bbBJAv6oqUcFXMHtGemWwui6FrsihtV1yGWc23OMfUmmO3ZoLbeS4nQ/RcIb+0RD aEmyYGD5XcVtteVDkI+ZRH4YcusukOBEDtqNiIQGwRZnijPVasmGucTTG7AObogyAODhE1TH3 ++cq0JYKTHDi+coRh7+9JPpfHpV6XFGoOxW X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 35564 Cc: Eli Zaretskii , 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Michael Heerdegen writes: > I skimmed through the changes and have installed it, but I didn't yet > try it. Will do ASAP, hopefully tonight. Ok, I did. It worked well without problems, and nicely indicates the questionable character(s). I dunno if the double emphasizing in the y-n-prompt (coloring + additional underlining with "^") is a bit too much. A bit related: Maybe the second line could be combined with the first line so that one line is saved. I mean, the prompt is four lines high with this change, quite a lot. Dunno what others think about it. Anyway, I like it. Thanks, Michael. From debbugs-submit-bounces@debbugs.gnu.org Mon Jul 29 14:16:09 2019 Received: (at 35564) by debbugs.gnu.org; 29 Jul 2019 18:16:09 +0000 Received: from localhost ([127.0.0.1]:49094 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hsABt-0002bO-Jk for submit@debbugs.gnu.org; Mon, 29 Jul 2019 14:16:09 -0400 Received: from bonobo.birch.relay.mailchannels.net ([23.83.209.22]:23172) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hsABq-0002bE-JV for 35564@debbugs.gnu.org; Mon, 29 Jul 2019 14:16:08 -0400 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 86595503160; Mon, 29 Jul 2019 18:16:05 +0000 (UTC) Received: from pdx1-sub0-mail-a43.g.dreamhost.com (100-96-11-214.trex.outbound.svc.cluster.local [100.96.11.214]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id AF2C65031DD; Mon, 29 Jul 2019 18:16:04 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from pdx1-sub0-mail-a43.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.17.5); Mon, 29 Jul 2019 18:16:05 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Descriptive-Callous: 1059d018422c3203_1564424165174_1632112057 X-MC-Loop-Signature: 1564424165174:1834092828 X-MC-Ingress-Time: 1564424165174 Received: from pdx1-sub0-mail-a43.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a43.g.dreamhost.com (Postfix) with ESMTP id 6853A8307F; Mon, 29 Jul 2019 11:16:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=linkov.net; bh=6z2LIcybTxLuAjVySRuM3NkXE4c=; b= cwUNxYPkvBDbmUMR+zxoKS4dKk67PfkHxvhlFCm7rRBA6lHeItzWf0oyXU7x1dR1 EUtYOfLas3dTnyHTlnsL9LEdlgRAd3zRBHSckyBg70CqnVrT/0PpeqL2+B7zoaD9 pnQf8KWDthttlgsP9xT75XTVdHeB8voQttQLLldOXgc= Received: from mail.jurta.org (m91-129-103-76.cust.tele2.ee [91.129.103.76]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a43.g.dreamhost.com (Postfix) with ESMTPSA id 8635483056; Mon, 29 Jul 2019 11:15:53 -0700 (PDT) X-DH-BACKEND: pdx1-sub0-mail-a43 From: Juri Linkov To: Michael Heerdegen Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters Organization: LINKOV.NET References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> <87wog3pewu.fsf@gmail.com> <87v9vndsnj.fsf@web.de> <87imrl4ixr.fsf@web.de> Date: Mon, 29 Jul 2019 21:11:08 +0300 In-Reply-To: <87imrl4ixr.fsf@web.de> (Michael Heerdegen's message of "Mon, 29 Jul 2019 05:29:36 +0200") Message-ID: <87lfwhf8w3.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain X-VR-OUT-STATUS: OK X-VR-OUT-SCORE: -100 X-VR-OUT-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeduvddrledugdduvdefucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuggftfghnshhusghstghrihgsvgdpffftgfetoffjqffuvfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufhofhffjgfkfgggtgesthdtredttdertdenucfhrhhomheplfhurhhiucfnihhnkhhovhcuoehjuhhriheslhhinhhkohhvrdhnvghtqeenucfkphepledurdduvdelrddutdefrdejieenucfrrghrrghmpehmohguvgepshhmthhppdhhvghlohepmhgrihhlrdhjuhhrthgrrdhorhhgpdhinhgvthepledurdduvdelrddutdefrdejiedprhgvthhurhhnqdhprghthheplfhurhhiucfnihhnkhhovhcuoehjuhhriheslhhinhhkohhvrdhnvghtqedpmhgrihhlfhhrohhmpehjuhhriheslhhinhhkohhvrdhnvghtpdhnrhgtphhtthhopehmihgthhgrvghlpghhvggvrhguvghgvghnseifvggsrdguvgenucevlhhushhtvghrufhiiigvpedt X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: npostavs@gmail.com, 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, =?iso-8859-1?Q?K=E9vin?= Le Gouguec X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > I dunno if the double emphasizing in the y-n-prompt (coloring + > additional underlining with "^") is a bit too much. A bit related: Maybe additional underlining should be used only when the current display doesn't support colors. > Maybe the second line could be combined with the first line so that one > line is saved. I mean, the prompt is four lines high with this change, > quite a lot. Dunno what others think about it. Then with using colors the prompt could fit into one line (when the display supports colors). From debbugs-submit-bounces@debbugs.gnu.org Mon Jul 29 15:02:14 2019 Received: (at 35564) by debbugs.gnu.org; 29 Jul 2019 19:02:14 +0000 Received: from localhost ([127.0.0.1]:49140 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hsAuU-00009c-5K for submit@debbugs.gnu.org; Mon, 29 Jul 2019 15:02:14 -0400 Received: from mail-wm1-f46.google.com ([209.85.128.46]:53506) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hsAuS-00009N-DB for 35564@debbugs.gnu.org; Mon, 29 Jul 2019 15:02:12 -0400 Received: by mail-wm1-f46.google.com with SMTP id x15so54836963wmj.3 for <35564@debbugs.gnu.org>; Mon, 29 Jul 2019 12:02:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=aRQyDNgtYQy/qxQO3lzKRNGeGaDzzdlVSGitbFb5nv8=; b=MWuceZ8qD+I86MgWvQcAeNdlC9VwADu8hnxjwr2mFME9U04eFE/sHfCDvJy0kv/QAn wyhni0S26YIR0RPGi4xP1hwISNoJ0VnX56xvzeCeVorOdT+JXUqE9/6JpGVnEVW/uVzH HwKogWPA0w7HGDJtHQkbSYLj+wVvOzlSMBTtdxCuEcTBJbPmrmXU70p7jSbjEgoV3jaF kd3ei9PwpRGwg4vIiwpsbATRzSzq5NuSYhh2t2GvdcdRogdtG/oE4NLPyKKEmVJxX3o8 IMKvWmd/NBOKWSsNgIASIj3hLL84eD5xvn05xYuLmdBa5kbvhBULnvMGhfA+7+aPpm5m ITLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=aRQyDNgtYQy/qxQO3lzKRNGeGaDzzdlVSGitbFb5nv8=; b=dxtsbXuGw99mgy01u0g07Tk1VL07ccPHD101Nyi3h40I9xkC2qrvcWEF/XPBLq622n 3hvvfFsVzrMJI9vggi4WODYsM5q6CwW5Aiz+mq/Ynyf3UJRrK8+XzEyCB1gHfsG7dZQe Hj/a39RE5/98/W3t5NRedQtCYZLYRYXS1qKvcTg86qQBNPYBrXBpXugxqjKha+Qm4oNG NX4Q+/PvE3gxGvQLcYsrfLocdcJWUKR5d3jCRWbWvLx+6wSpNPLVq4Akc8pa6lyianz/ 0Kb5LnCSMg0NjPkeMK/eT3cSeWQ5lC9rLYhbLtctx60PkiGfT4t+DMnS0rw+HAYAtyDs Rzxg== X-Gm-Message-State: APjAAAUV70g2kiysn5OWwDz4dFi1FZhkTSGP334EpkFOHcwzMhx/viOr 79+JnB9arqejHwkvx0tZTgU= X-Google-Smtp-Source: APXvYqzi3fepklfWmYCUPE9GPma7gd/OKo3rPAP27DUgvPKCh4s6AbOCvS2+DuiwEh1uedblqsOMcA== X-Received: by 2002:a7b:cbcb:: with SMTP id n11mr25263588wmi.146.1564426926582; Mon, 29 Jul 2019 12:02:06 -0700 (PDT) Received: from my-little-tumbleweed (71.142.13.109.rev.sfr.net. [109.13.142.71]) by smtp.gmail.com with ESMTPSA id j33sm130914762wre.42.2019.07.29.12.02.04 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Mon, 29 Jul 2019 12:02:05 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Michael Heerdegen Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> <87wog3pewu.fsf@gmail.com> <87v9vndsnj.fsf@web.de> <87imrl4ixr.fsf@web.de> Date: Mon, 29 Jul 2019 21:01:58 +0200 In-Reply-To: <87imrl4ixr.fsf@web.de> (Michael Heerdegen's message of "Mon, 29 Jul 2019 05:29:36 +0200") Message-ID: <87r2688y1l.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Eli Zaretskii , 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Michael Heerdegen writes: > I dunno if the double emphasizing in the y-n-prompt (coloring + > additional underlining with "^") is a bit too much. The patch series started out with just the coloring, which we figured might have accessibility issues on its own (we can't assume that the user can distinguish colors); we added the '^' markers to alleviate this; then=E2=80=A6 > A bit related: > Maybe the second line could be combined with the first line so that one > line is saved. (Assuming the first line you mention is "Confirm" and the second line is the command, which would make the '^' markers the third line; apologies if I misunderstood) =E2=80=A6 I realized that when the user fails to answer 'y' or 'n', y-or-n-p prepends "Please answer y or n." to the prompt, i.e. this=E2=80=A6 sed 's/?/!/' ^ =E2=80=A6 becomes this: Please answer y or n. sed 's/?/!/' ^ AFAICT, this means that we need a newline *before* the command (unless we add an optional RETRY-PROMPT argument to y-or-n-p or something). (I added comments to try to explain this in dired--no-subst-prompt; tell me if they need more work.) > I mean, the prompt is four lines high with this change, > quite a lot. Dunno what others think about it. It is fairly more heavyweight than before. And the irony is, I am still not 100% satisfied with it; I worry that the user will take "Send 1 occurrence of `*' as-is to shell?" to mean "Escape 1 occurrence of `*' so that the shell leaves it as-is?". Tell me if the shed is about to crumble under the weight of paint, but if we are fine with so many lines, could we perhaps rephrase=E2=80=A6 > Confirm > sed 's/?/!/' > ^ > Send 1 occurrence of `?' as-is to shell? =E2=80=A6 to: > Warning: the shell may interpret 1 occurrence of `?' as wildcard: > sed 's/?/!/' > ^ > Proceed anyway? --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Tweak-dired-do-shell-command-warning-some-more.patch >From 97d5ec40ccbb3a2d366aaa05b45e29690ee5288a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Mon, 29 Jul 2019 20:48:53 +0200 Subject: [PATCH] Tweak dired-do-shell-command warning some more * lisp/dired-aux.el (dired--no-subst-prompt): Clarify what we are concerned about. (bug#28969, bug#35564) --- lisp/dired-aux.el | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 3887d75356..35052785ba 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -120,17 +120,18 @@ dired--no-subst-prompt ;; text will shove the command to the right, and the '^' markers ;; will become misaligned. (apply #'concat - `("Confirm:\n" + `(,(format-message + (ngettext + "Warning: the shell may interpret %d occurrence of `%s' as wildcard:\n" + "Warning: the shell may interpret %d occurrences of `%s' as wildcards:\n" + (length char-positions)) + (length char-positions) + (propertize (string (aref command (car char-positions))) + 'face 'warning)) ,command "\n" ,@(when add-markers (list (dired--mark-positions char-positions) "\n")) - ,(format-message - (ngettext "Send %d occurrence of `%s' as-is to shell?" - "Send %d occurrences of `%s' as-is to shell?" - (length char-positions)) - (length char-positions) - (propertize (string (aref command (car char-positions))) - 'face 'warning))))) + "Proceed anyway?"))) ;;;###autoload (defun dired-diff (file &optional switches) -- 2.22.0 --=-=-= Content-Type: text/plain (Can be applied on top of the patch series or the squashed patch; if the latter, the commit message can be discarded. Tests unchanged, since they only look at the command and the markers.) If everybody likes the prompt well enough without this umpteenth tweak, it's fine by me. Thank you all for your patience. --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Fri Aug 02 01:32:08 2019 Received: (at 35564) by debbugs.gnu.org; 2 Aug 2019 05:32:08 +0000 Received: from localhost ([127.0.0.1]:55699 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1htQAi-0002h5-Ba for submit@debbugs.gnu.org; Fri, 02 Aug 2019 01:32:08 -0400 Received: from mout.web.de ([212.227.15.14]:54399) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1htQAf-0002gb-Qe for 35564@debbugs.gnu.org; Fri, 02 Aug 2019 01:32:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1564723915; bh=ZlTSSi1cQZLbMDRblf4IhqooCjONqHyC9pq5+wMWjRE=; h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To; b=bTU9Pl3a3l382ZEkzpQqhIF339Wyi/L59w0P8USS1Br+dDrpGI36IFsJEEYnVUxW9 6Tja/BI8au/YWum293cmPe0Rr/mloCgHmXiP1px/R5uGRd4iQHv8BqsIL9k+/6A27Z PihlW5az2vMYQzb3oBbNvpWoaE/6zYpG5fl0ByXI= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from drachen.dragon ([92.208.178.242]) by smtp.web.de (mrweb003 [213.165.67.108]) with ESMTPSA (Nemesis) id 0MLxrY-1i18Fv1YyK-007jbL; Fri, 02 Aug 2019 07:26:39 +0200 From: Michael Heerdegen To: =?utf-8?Q?K=C3=A9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> <87wog3pewu.fsf@gmail.com> <87v9vndsnj.fsf@web.de> <87imrl4ixr.fsf@web.de> <87r2688y1l.fsf@gmail.com> Date: Fri, 02 Aug 2019 07:26:36 +0200 In-Reply-To: <87r2688y1l.fsf@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Mon, 29 Jul 2019 21:01:58 +0200") Message-ID: <87sgqkjfxv.fsf@web.de> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:ruTzfAvZ/GKsjVrmqOes/bpsgLRWxTleIKt0kgvUQydfP6EdM4A wXiXdemHiUay744iYmaMo4gxyaJlaqNPxfes8BEyuYN9UZuM3z6KPLI8s3MhiMd5MXIOn5B SBOOWe3PpmRZezOh4KxKwlMTG450uBw5GsHNyj6tiY5BkZRnw2zF1f7Yi6AoUDaRTm7Don+ usQGWsoe0HmbulxqDSoZw== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:IjpjmKqAIUM=:enDrWjMNM7AChrwf47ZWfg iawLuesVonJ7Ah92iZ9O5+YINnfPUK5ZOHdCjv+o3QZmT7F1vT2qrSvtcZuXW+OrQQHBiV0pm 3+jFdBE7p7yl6uNaSg9mqvY3x6OuBtkVgqOnkaCMT7y45DGCRAJ9hXYEtR3QMLzDmlEiRxHV0 OSXZCY7hPWqbEcq8o2YyjNmYB9PFDqSQg8l4fPi83tgUo07VdpU1OzeJpkgK1dcyV2snNRuM7 boRg9UNhpGOaikLhhy8ep8XP90aihczv7MB+ytJZ80nUer9Nn/rJX5AtWOiut/VmN1XL2luJ6 c2QHIIeA2YTEcdeD5J16//3Izc3rmuFCEaRw1s5jbgnpO5IXmirWHFCItqOj1G7oZ5cAsyMwc nh1g0F3ze4o+048DD8yZwpSgKPz9lND0ctMvDkQXXyqx+ebpYWqzwFAk5mp4sXoOGvTqHNPjM JsyYaOrH+zOEsyYM4NjzCfTS+o0tHMWShu/TK69As08qwovg5Jq4YDu6lzZQx4lqCXmC5aXrU MX9cQjaHKbqRL/SHnf4O6uEZNXioF/gLiUrkKpwMcWDbH4xufO4JIN8mAoPZmswjDrQboDi6U bGpVIlwg9gRBGU3GNlCXMmaJ/NBRWG0ea5C2Esl3GkAiMWwlRkjEpL22uSwNI1e6YILKEs+Fm cSaPmK72TD2/7/9bwHiIr7ktVJD/rAIDtNHbGPDOEC20eTeLKi68tI/FWqbhGR5saFghBHUPw e4SOmw6whVKcmwAllmosFnXHPMg4gEKig9kVuC3v5SOZ0N1WP6fIchsJV383+aT3vyO3aJgix RNVj5Tixo0wGexnQbdNQvO2JhLmRpO6Hbfo8NLEK1MlAhASj7PYOwR1YV6mR5uJoIHgE9kP1A +KzZtB1xJEoCbNs7Zr92iJue6INbz0e0EI1zr0PnjIv5HpE88bC0QZ4cW2F6jYh1I8YcW69dF DzYSsGYK8jcerouq4plq42nIafXumBFdxvOW5BZKFK+kZnwVpO6ckDwWQSrcrB4sFTVN5eOiP JCz/RzVCdpzRNzDyK55PPVDKuCto9AeO4mA3JkPxMKN1jmlfj9Jveyz+uhCN7dNf7DKj/NCt6 STj4WAX4Y+jMU4wuCuFJM/fjyy9QKgKjb1aMOROIhyqRynHSLYYfs0OcRG6g39XM+Jgbi57Of +nZj8= X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) K=C3=A9vin Le Gouguec writes: > > I dunno if the double emphasizing in the y-n-prompt (coloring + > > additional underlining with "^") is a bit too much. > > The patch series started out with just the coloring, which we figured > might have accessibility issues on its own (we can't assume that the > user can distinguish colors); we added the '^' markers to alleviate > this; then=E2=80=A6 Yeah, as mentioned, when coloring is possible, I would also just leave out the ^ underlining. > (Assuming the first line you mention is "Confirm" and the second line is > the command, which would make the '^' markers the third line; apologies > if I misunderstood) Yes, I suggested to combine Confirm... with the command in the first line. > =E2=80=A6 I realized that when the user fails to answer 'y' or 'n', y-or-= n-p > prepends "Please answer y or n." to the prompt, i.e. this=E2=80=A6 > > sed 's/?/!/' > ^ > > =E2=80=A6 becomes this: > > Please answer y or n. sed 's/?/!/' > ^ > > AFAICT, this means that we need a newline *before* the command (unless > we add an optional RETRY-PROMPT argument to y-or-n-p or something). > > (I added comments to try to explain this in dired--no-subst-prompt; tell > me if they need more work.) Looks fine. > And the irony is, I am still not 100% satisfied with it; I worry that > the user will take "Send 1 occurrence of `*' as-is to shell?" to mean > "Escape 1 occurrence of `*' so that the shell leaves it as-is?". > > Tell me if the shed is about to crumble under the weight of paint, No, a valid concern, and it's good that you noticed. > but if we are fine with so many lines, could we perhaps rephrase=E2=80=A6 > > > Confirm > > sed 's/?/!/' > > ^ > > Send 1 occurrence of `?' as-is to shell? > > =E2=80=A6 to: > > > Warning: the shell may interpret 1 occurrence of `?' as wildcard: > > sed 's/?/!/' > > ^ > > Proceed anyway? I'm not happy with that either. Look at it: there are quotes around the critical part, so the user might become crazy trying to find out why Emacs thinks the shell might interpret that as a wildcard. The highlighting even more makes it look like there is something wrong with the command. Even "proceed anyway" as you chose makes it sound like this is an exception/ something wrong although it is totally legitimate. Maybe just telling what dired did not do would be better? Like "N occurrences of X will not be replaced with the file/file list - proceed? Because, there are two things we mix up: (1) dired does not substitute with files, though the user might have wanted that, and (2) the char is send to the shell and is a wildcard there, so the result might also not be what the user intended. Do we want to warn about (1) or (2)? Both seems to be too much for one line of text. If we don't find a good wording maybe use something like `read-multiple-choice' or some other mechanism where the user is allowed to hit a help key (?, and that key should also be visible in the prompt). We can leave an explanation that doesn't have to fit into one line in the help text. I only mention `read-multiple-choice' because it provides all of that out of the box, of course there are alternative ways. Michael. From debbugs-submit-bounces@debbugs.gnu.org Thu Aug 08 06:40:14 2019 Received: (at 35564) by debbugs.gnu.org; 8 Aug 2019 10:40:14 +0000 Received: from localhost ([127.0.0.1]:39967 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hvfq9-0004te-Na for submit@debbugs.gnu.org; Thu, 08 Aug 2019 06:40:14 -0400 Received: from mail-wm1-f44.google.com ([209.85.128.44]:36311) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hvfq8-0004tO-2f for 35564@debbugs.gnu.org; Thu, 08 Aug 2019 06:40:12 -0400 Received: by mail-wm1-f44.google.com with SMTP id g67so1911801wme.1 for <35564@debbugs.gnu.org>; Thu, 08 Aug 2019 03:40:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=1o9+YTpAW6qlZO8YFvbPezXiltVbtL8n+5BObfySA08=; b=puXF3mECsL633vODi6Viq/SExA7NIKUDUAFxbgmH4MbHgX78bwZoFheWpXmTbS/jp7 +ulT/2rF2QR6n8s+hQeNJX1vWUMmJmRByGVvyPTMu2u3IBSi7Mr0wYj+Q2AGkX+t6rVp TTelbjE2NGw1eXSwcsJtBTlWoSM06YC3JRKNK9LG3oad4FDJ01N1XKVxb9nlXlDqA1r6 4ivYeqx8ykSZwzmA7cjo3jZYLCHe1tEpLIdWGlaHsvjbKofbrjUin6NK3RxG7maDnAlm Y/mh8C9OlL2xjoF8kPHXdPFWkHXqojNjsmrtLNq9IvS5Xzdy1d3D6+IYck8GwKokTh37 Lhpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=1o9+YTpAW6qlZO8YFvbPezXiltVbtL8n+5BObfySA08=; b=XTDQR0PzRYFHgJObXeWTz5HtpyiL0lCdAR2VJTNfcS7gc5RJxB8HDe6T1MaxpHx5eJ M+o/EhdIt9hJ7eZVtzsvUURMdvGGXSUv+NPI3WInLNTosYtI9DsSoY3jh4vuuTD1SoJI repzwvoiHnhRyKiamqUzi8CTZmVpDMjkp5oXDxDfDvnuSqT9/dgXtAYPYFpRvVZpU4TR P5XH9ZmbzjffKtbO5vADKaVQ8G5Hx40LNVoYVJvvSYnyFJUXOXNpY1nwCIXE6GGODi6p 5SJjMvepO/SFwWCaQ5x2mTsyQSHKh7jkhhVHj/SGQpwwMm+wpuj+GMkPdN/3SjfdILdT 6jSg== X-Gm-Message-State: APjAAAXuyLfIH7MNfq0h8ZHv00NLt7iy6YdyxuxtafRQv1tDU0OVcGnF NuYy9FI2wv0RPPQEHpvbFk8= X-Google-Smtp-Source: APXvYqxBvksmIB189mpdhkWOEtOBAaY3+2Vjxh/lYtjxLbFWed4v1v9DwPqIn+sh9/0JcAsxT5tdQg== X-Received: by 2002:a1c:a70d:: with SMTP id q13mr3797934wme.26.1565260806267; Thu, 08 Aug 2019 03:40:06 -0700 (PDT) Received: from nc10-laptop (2a01cb04010fc800c8771fb97d0446e3.ipv6.abo.wanadoo.fr. [2a01:cb04:10f:c800:c877:1fb9:7d04:46e3]) by smtp.gmail.com with ESMTPSA id k9sm29661398wrd.46.2019.08.08.03.40.05 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 08 Aug 2019 03:40:05 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Michael Heerdegen Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> <87wog3pewu.fsf@gmail.com> <87v9vndsnj.fsf@web.de> <87imrl4ixr.fsf@web.de> <87r2688y1l.fsf@gmail.com> <87sgqkjfxv.fsf@web.de> Date: Thu, 08 Aug 2019 12:40:03 +0200 In-Reply-To: <87sgqkjfxv.fsf@web.de> (Michael Heerdegen's message of "Fri, 02 Aug 2019 07:26:36 +0200") Message-ID: <87tvas2b5o.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Juri Linkov , 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) First, apologies for taking so long to respond - I was AFK last week. I might not be very reactive these coming weeks either. Michael Heerdegen writes: > Yeah, as mentioned, when coloring is possible, I would also just leave > out the ^ underlining. OK. What exactly do we mean by "coloring is possible"? 1. "Does the warning face have a distinct foreground or background from the prompt face?" 2. "Are the colors distinguishable enough?" (e.g. what shr-color-visible tries to guess IIUC) 3. Something else? What bothers me is that even if we can assert #2, nothing guarantees that these colors will be distinguishable *to the user* (who may e.g. have some form of color blindness). It would therefore be nice if this user could force Emacs to use ^ markers; I guess that would involve a new variable. I stayed away from this path because I wasn't convinced that we needed a full-blown customization option for a supposedly rare branch in dired-do-shell-command, and that we could live with the redundant coloring plus underlining. I'd be happy to make the prompt more succinct, as soon as I'm sure I understand what we mean by "coloring is possible"! >> > Warning: the shell may interpret 1 occurrence of `?' as wildcard: >> > sed 's/?/!/' >> > ^ >> > Proceed anyway? > > I'm not happy with that either. Look at it: there are quotes around the > critical part, so the user might become crazy trying to find out why > Emacs thinks the shell might interpret that as a wildcard. Right. Becoming crazy because Emacs sees phantom wildcards is the reason why I started this bug report; I hoped that by saying "*may* interpret", the user would understand that Emacs is basically saying "this looks like a common footgun; I don't speak shell though so you tell me". > Maybe just telling what dired did not do would be better? Like > "N occurrences of X will not be replaced with the file/file list - > proceed? That would be the most correct description of the situation. I didn't go that way because the user might not be aware of this feature; I failed to come up with a short prompt that would 1. explain the substitution feature and 2. explain why Dired will not activate it here. > Because, there are two things we mix up: (1) dired does not substitute > with files, though the user might have wanted that, and (2) the char is > send to the shell and is a wildcard there, so the result might also not > be what the user intended. Do we want to warn about (1) or (2)? Both > seems to be too much for one line of text. Very much agreed. > If we don't find a good wording maybe use something like > `read-multiple-choice' or some other mechanism where the user is allowed > to hit a help key (?, and that key should also be visible in the > prompt). We can leave an explanation that doesn't have to fit into one > line in the help text. I only mention `read-multiple-choice' because it > provides all of that out of the box, of course there are alternative > ways. That sounds like a good compromise. I'll see what I can come up with. From debbugs-submit-bounces@debbugs.gnu.org Thu Aug 08 17:22:35 2019 Received: (at 35564) by debbugs.gnu.org; 8 Aug 2019 21:22:36 +0000 Received: from localhost ([127.0.0.1]:41811 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hvprl-0001PS-9h for submit@debbugs.gnu.org; Thu, 08 Aug 2019 17:22:33 -0400 Received: from aye.elm.relay.mailchannels.net ([23.83.212.6]:43259) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hvpri-0001PJ-Ub for 35564@debbugs.gnu.org; Thu, 08 Aug 2019 17:22:31 -0400 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id E2A566A23DA; Thu, 8 Aug 2019 21:22:29 +0000 (UTC) Received: from pdx1-sub0-mail-a13.g.dreamhost.com (100-96-84-130.trex.outbound.svc.cluster.local [100.96.84.130]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 6BBB26A2A9B; Thu, 8 Aug 2019 21:22:29 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from pdx1-sub0-mail-a13.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.17.5); Thu, 08 Aug 2019 21:22:29 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Left-Whispering: 451a141a395a769b_1565299349744_316018229 X-MC-Loop-Signature: 1565299349743:839775415 X-MC-Ingress-Time: 1565299349743 Received: from pdx1-sub0-mail-a13.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a13.g.dreamhost.com (Postfix) with ESMTP id 2D8C1806F5; Thu, 8 Aug 2019 14:22:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; s=linkov.net; bh=NG+n/D t/KKqgeKUOruskLJb8X7c=; b=pMghSZhuW4DUWN8dduPUynXS6EmTev5gXfo1uE 1fpHhosffD9FSvcj5II/unCF+lE0fDhhmxIhO9pdTbtsaxrKWHYr+dproAo7Fakw 9TolYtlAXV7kDuPmMSq2h3+tVA9ceM//PlAuGMARGL+hSwhUpWh9cqstgmnj/qU9 Bp8M0= Received: from mail.jurta.org (m91-129-103-91.cust.tele2.ee [91.129.103.91]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a13.g.dreamhost.com (Postfix) with ESMTPSA id BD12D806E3; Thu, 8 Aug 2019 14:22:19 -0700 (PDT) X-DH-BACKEND: pdx1-sub0-mail-a13 From: Juri Linkov To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> <87wog3pewu.fsf@gmail.com> <87v9vndsnj.fsf@web.de> <87imrl4ixr.fsf@web.de> <87r2688y1l.fsf@gmail.com> <87sgqkjfxv.fsf@web.de> <87tvas2b5o.fsf@gmail.com> Date: Fri, 09 Aug 2019 00:06:33 +0300 In-Reply-To: <87tvas2b5o.fsf@gmail.com> (=?iso-8859-1?Q?=22K=E9vin?= Le Gouguec"'s message of "Thu, 08 Aug 2019 12:40:03 +0200") Message-ID: <87d0hffjda.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 X-VR-OUT-STATUS: OK X-VR-OUT-SCORE: -100 X-VR-OUT-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeduvddrudduhedgudegvdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucggtfgfnhhsuhgsshgtrhhisggvpdfftffgtefojffquffvnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvffufhffjgfkfgggtgfgsehtkeertddtreejnecuhfhrohhmpefluhhrihcunfhinhhkohhvuceojhhurhhisehlihhnkhhovhdrnhgvtheqnecukfhppeeluddruddvledruddtfedrledunecurfgrrhgrmhepmhhouggvpehsmhhtphdphhgvlhhopehmrghilhdrjhhurhhtrgdrohhrghdpihhnvghtpeeluddruddvledruddtfedrledupdhrvghtuhhrnhdqphgrthhhpefluhhrihcunfhinhhkohhvuceojhhurhhisehlihhnkhhovhdrnhgvtheqpdhmrghilhhfrhhomhepjhhurhhisehlihhnkhhovhdrnhgvthdpnhhrtghpthhtohepkhgvvhhinhdrlhgvghhouhhguhgvtgesghhmrghilhdrtghomhenucevlhhushhtvghrufhiiigvpedt Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > First, apologies for taking so long to respond - I was AFK last week. = I > might not be very reactive these coming weeks either. I use the substitution feature in dired-do-shell-command quite rarely, but today I needed to use it, and it strikes as partly unusable and confusing. There are several problems: 1. Answering "no" cancels the command. Instead of this, it should proceed without substitution. There is a special key `C-g' to cancel the command. 2. The current question is too ambiguous: Confirm--do you mean to use =E2=80=98?=E2=80=99 as a wildcard? (y or n) A wildcard can mean both dired substitution and shell substitution. A better question should use the same terms as documented in the docstring of `dired-do-shell-command', i.e. "marked files", "file list". So a better question would be: Confirm--do you mean to substitute =E2=80=98?=E2=80=99 with marked file= s? (y or n) Or something similar that makes clear that substitution applies to dired files, not files matched by shell. 3. I still can't be sure if after asking these question, dired still does the right thing. I'd prefer to have an option to show the final command before running it, exactly like `C-u M-x rgrep' does with its `confirm' argument. Yes, its command line is quite long, but this is not a problem: wrapped minibuffer content is less problematic than multi-line prompts. > What bothers me is that even if we can assert #2, nothing guarantees > that these colors will be distinguishable *to the user* (who may > e.g. have some form of color blindness). It would therefore be nice if > this user could force Emacs to use ^ markers; I guess that would involv= e > a new variable. As was already discussed in this thread, using (:inherit '(warning underl= ine)) will solve this problem and improve accessibility. So there will be no need in multi-line prompt when using underline face attribute. From debbugs-submit-bounces@debbugs.gnu.org Fri Aug 09 08:43:24 2019 Received: (at 35564) by debbugs.gnu.org; 9 Aug 2019 12:43:24 +0000 Received: from localhost ([127.0.0.1]:42132 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hw4Eu-0007rZ-1t for submit@debbugs.gnu.org; Fri, 09 Aug 2019 08:43:24 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:33574) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hw4Es-0007rM-G7 for 35564@debbugs.gnu.org; Fri, 09 Aug 2019 08:43:23 -0400 Received: by mail-wr1-f67.google.com with SMTP id n9so98237738wru.0 for <35564@debbugs.gnu.org>; Fri, 09 Aug 2019 05:43:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=uUqSjynX8LJX1p7IFxS057aC711CPYEur3A1lCCs+R4=; b=eAzd3cGg6REEdD4YV+WTEWTZptwHJBqQRMAY18vgITokbHU6BNjyyn6gmO6Vxzwrl+ xSSyF7bIi/jxzobfGA2jtWmDTfTlhhTv3Pgnw4U36uj3rISXd1f6ZcqzveMIbjyUZaoC kI9BgnUOHmbbUQOZ4+DfRw6B7gCiK5WWo7B9jtZDDUFxoob7jjubB8fo0oPPzTj0pKcG ixy6OAs37EVQoAHfZ0ohtTiCoucmx4/rwyMzajHrKl0SHp2/UtioekZk1yRoZxHKFjL5 xW6T1748SvSTH+RRizY1uxW1RrZBh1OR1m72wUMxZc/zZFaMP1/aqgCXsgmzYTEg3ueW ZqdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=uUqSjynX8LJX1p7IFxS057aC711CPYEur3A1lCCs+R4=; b=R7tOxx7ACGqD8VtyxlxtIG+Q8guTkhsV9/xiu64uorWvvodpIhPqEUckJ2y6HfIV6v YlsmXooh3AvlYA/ItqXfsbp5HZ16wKP4WclwV7X7AnJwnl/7ThIr0wssneGGPQgdp7TC h9dqHYQJvk2PZBY54CFjzoeHntU6K2qzRlM/Lvid782txnGTePo0QlfYIkDgfFYJLJPf 0mhkSiZ8Z24UMSfsvim6OJxnlwxIfxEqq61pT13JaoPM3wA3zBpRlpTk1thwVUf0Cr61 JDHejzKvmJaq4vjoNIloh5Q6VqMfpr8MWoFdPCx7jLPvJbPxwoC5qm6XbphGSMCFut4N n22A== X-Gm-Message-State: APjAAAXR/KKXyUf9Ou5CJ5RdyguvZ81PGJ/yPTILxfB79vlq0bjyB/sO 3S5n6N8sO+tLs1rupEaU/+s= X-Google-Smtp-Source: APXvYqwH3Hnw40GMH08Kg1hC7UH+KiJDef+jzVg6FE3A7Pro1bmpUhlyz6snBndC0i4PTfi5/F824Q== X-Received: by 2002:adf:e5c4:: with SMTP id a4mr9353231wrn.87.1565354596575; Fri, 09 Aug 2019 05:43:16 -0700 (PDT) Received: from nc10-laptop (2a01cb04010fc800c8771fb97d0446e3.ipv6.abo.wanadoo.fr. [2a01:cb04:10f:c800:c877:1fb9:7d04:46e3]) by smtp.gmail.com with ESMTPSA id c1sm216774828wrh.1.2019.08.09.05.43.13 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 09 Aug 2019 05:43:13 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Juri Linkov Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> <87wog3pewu.fsf@gmail.com> <87v9vndsnj.fsf@web.de> <87imrl4ixr.fsf@web.de> <87r2688y1l.fsf@gmail.com> <87sgqkjfxv.fsf@web.de> <87tvas2b5o.fsf@gmail.com> <87d0hffjda.fsf@mail.linkov.net> Date: Fri, 09 Aug 2019 14:43:12 +0200 In-Reply-To: <87d0hffjda.fsf@mail.linkov.net> (Juri Linkov's message of "Fri, 09 Aug 2019 00:06:33 +0300") Message-ID: <87k1bmfr1b.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Juri Linkov writes: > I use the substitution feature in dired-do-shell-command quite rarely, > but today I needed to use it, and it strikes as partly unusable > and confusing. Welcome to the club :) > 2. The current question is too ambiguous: > > Confirm--do you mean to use =E2=80=98?=E2=80=99 as a wildcard? (y or n) > > A wildcard can mean both dired substitution and shell substitution. > A better question should use the same terms as documented in the > docstring of `dired-do-shell-command', i.e. "marked files", "file list". > So a better question would be: > > Confirm--do you mean to substitute =E2=80=98?=E2=80=99 with marked file= s? (y or n) > > Or something similar that makes clear that substitution applies > to dired files, not files matched by shell. Mmm, I think that the current prompt *does* use the same terms as documented in the docstring: it simply mistakenly assumes that if '?' and '*' are not "isolated", the shell will unconditionally process them as wildcards. It is a heuristic that fails to consider that '?' and '*' may be quoted or escaped. So with this prompt, "yes" means "yes, I want the shell to (possibly) substitute these characters", while "no" means "By Jove, what a silly mistake I was about to make! Thank you ever so much for catching it Dired old chap! Let me add some backquotes around this '?' so that you can be sure I mean for you to substitute it for the marked files." IIUC, your suggested prompt does not match what dired-do-shell-command actually does: the function only ever substitutes '?' if it is "isolated", i.e. surrounded with whitespace or backquotes. Cf. the docstring: > =E2=80=98*=E2=80=99 and =E2=80=98?=E2=80=99 when not surrounded by whites= pace nor =E2=80=98`=E2=80=99 have no special > significance for =E2=80=98dired-do-shell-command=E2=80=99, and are passed= through > normally to the shell, but you must confirm first. (Drew suggested that we may want to change *the code* to behave as your prompt suggests[1], I sketched a possible way to let the user select which occurrences to substitute[2], but did not act on it as AFAICT this use-case is already handled by adding backquotes around '?') >> What bothers me is that even if we can assert #2, nothing guarantees >> that these colors will be distinguishable *to the user* (who may >> e.g. have some form of color blindness). It would therefore be nice if >> this user could force Emacs to use ^ markers; I guess that would involve >> a new variable. > > As was already discussed in this thread, using (:inherit '(warning underl= ine)) > will solve this problem and improve accessibility. So there will be > no need in multi-line prompt when using underline face attribute. Mmm. I went to a TTY to check how (:inherit '(underline)) looks. Since (display-supports-face-attributes-p '(:underline t)) is nil there, the "underline" face is defined as (:weight bold), which merely makes the foreground color brighter. So (:inherit '(warning underline)) amounts to just (:inherit '(warning)). Perhaps (display-supports-face-attributes-p '(:underline t)) can be used to decide whether we need to add ^ markers. [1] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D35564#89 [2] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D28969#19 From debbugs-submit-bounces@debbugs.gnu.org Fri Aug 09 14:10:29 2019 Received: (at 35564) by debbugs.gnu.org; 9 Aug 2019 18:10:29 +0000 Received: from localhost ([127.0.0.1]:43240 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hw9LR-0007wR-68 for submit@debbugs.gnu.org; Fri, 09 Aug 2019 14:10:29 -0400 Received: from anteater.elm.relay.mailchannels.net ([23.83.212.3]:35547) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hw9LO-0007wC-3A for 35564@debbugs.gnu.org; Fri, 09 Aug 2019 14:10:26 -0400 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id D90DF1A2D58; Fri, 9 Aug 2019 18:10:24 +0000 (UTC) Received: from pdx1-sub0-mail-a11.g.dreamhost.com (100-96-4-86.trex.outbound.svc.cluster.local [100.96.4.86]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 2DC9D1A2D09; Fri, 9 Aug 2019 18:10:22 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from pdx1-sub0-mail-a11.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.17.5); Fri, 09 Aug 2019 18:10:24 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Cooing-Callous: 1b4fede61a17664c_1565374222549_2203405489 X-MC-Loop-Signature: 1565374222549:4231441895 X-MC-Ingress-Time: 1565374222549 Received: from pdx1-sub0-mail-a11.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a11.g.dreamhost.com (Postfix) with ESMTP id DEB27835BD; Fri, 9 Aug 2019 11:10:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; s=linkov.net; bh=ww+Lbh 9ZNLQNCygbdu8Dc/1+3Og=; b=uo5UyKjDYHe4ExQeE9iZMDGEFEMglIt7vO+Vac 8eBXxeTWfJm9mvWHFhaIjwBPSOnuw+9QvKeYFJgKDciVQiPmD+NihXfZ64TZA1FO dORLXU3KyUwNQ0JLQs4F0eGV8i8jiCZRRK31R53H07V1eQ3mjFetZXpYNFkFEhCR jXOog= Received: from mail.jurta.org (m91-129-103-91.cust.tele2.ee [91.129.103.91]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a11.g.dreamhost.com (Postfix) with ESMTPSA id E887183527; Fri, 9 Aug 2019 11:10:13 -0700 (PDT) X-DH-BACKEND: pdx1-sub0-mail-a11 From: Juri Linkov To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters Organization: LINKOV.NET References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> <87wog3pewu.fsf@gmail.com> <87v9vndsnj.fsf@web.de> <87imrl4ixr.fsf@web.de> <87r2688y1l.fsf@gmail.com> <87sgqkjfxv.fsf@web.de> <87tvas2b5o.fsf@gmail.com> <87d0hffjda.fsf@mail.linkov.net> <87k1bmfr1b.fsf@gmail.com> Date: Fri, 09 Aug 2019 21:03:49 +0300 In-Reply-To: <87k1bmfr1b.fsf@gmail.com> (=?iso-8859-1?Q?=22K=E9vin?= Le Gouguec"'s message of "Fri, 09 Aug 2019 14:43:12 +0200") Message-ID: <87wofm8bcq.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 X-VR-OUT-STATUS: OK X-VR-OUT-SCORE: -100 X-VR-OUT-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeduvddruddujedguddvudcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucggtfgfnhhsuhgsshgtrhhisggvpdfftffgtefojffquffvnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvffuohhfffgjkfgfgggtgfesthekredttderjeenucfhrhhomheplfhurhhiucfnihhnkhhovhcuoehjuhhriheslhhinhhkohhvrdhnvghtqeenucfkphepledurdduvdelrddutdefrdeludenucfrrghrrghmpehmohguvgepshhmthhppdhhvghlohepmhgrihhlrdhjuhhrthgrrdhorhhgpdhinhgvthepledurdduvdelrddutdefrdeluddprhgvthhurhhnqdhprghthheplfhurhhiucfnihhnkhhovhcuoehjuhhriheslhhinhhkohhvrdhnvghtqedpmhgrihhlfhhrohhmpehjuhhriheslhhinhhkohhvrdhnvghtpdhnrhgtphhtthhopehkvghvihhnrdhlvghgohhughhuvggtsehgmhgrihhlrdgtohhmnecuvehluhhsthgvrhfuihiivgeptd Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) >> 2. The current question is too ambiguous: >> >> Confirm--do you mean to use =E2=80=98?=E2=80=99 as a wildcard? (y or= n) >> >> A wildcard can mean both dired substitution and shell substitution. >> A better question should use the same terms as documented in the >> docstring of `dired-do-shell-command', i.e. "marked files", "file list= ". >> So a better question would be: >> >> Confirm--do you mean to substitute =E2=80=98?=E2=80=99 with marked f= iles? (y or n) >> >> Or something similar that makes clear that substitution applies >> to dired files, not files matched by shell. > > Mmm, I think that the current prompt *does* use the same terms as > documented in the docstring: it simply mistakenly assumes that if '?' > and '*' are not "isolated", the shell will unconditionally process them > as wildcards. It is a heuristic that fails to consider that '?' and '*= ' > may be quoted or escaped. Do you mean this case: despite that the docstring of `dired-do-shell-command' mentions "a shell wildcard", typing on a file: ! cat '*' and confirming with `y': Confirm--do you mean to use =E2=80=98*=E2=80=99 as a wildcard? (y or n)= y still doesn't use * as "a shell wildcard". Then I agree. >> As was already discussed in this thread, using (:inherit '(warning und= erline)) >> will solve this problem and improve accessibility. So there will be >> no need in multi-line prompt when using underline face attribute. > > Mmm. I went to a TTY to check how (:inherit '(underline)) looks. Sinc= e > (display-supports-face-attributes-p '(:underline t)) is nil there, the > "underline" face is defined as (:weight bold), which merely makes the > foreground color brighter. So (:inherit '(warning underline)) amounts > to just (:inherit '(warning)). > > Perhaps (display-supports-face-attributes-p '(:underline t)) can be use= d > to decide whether we need to add ^ markers. You can check all possible face attributes to find the one available on tty: underline, weight: bold, inverse-video, ... From debbugs-submit-bounces@debbugs.gnu.org Thu Aug 15 16:59:29 2019 Received: (at 35564) by debbugs.gnu.org; 15 Aug 2019 20:59:29 +0000 Received: from localhost ([127.0.0.1]:52513 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hyMqH-0000Bl-5t for submit@debbugs.gnu.org; Thu, 15 Aug 2019 16:59:29 -0400 Received: from camel.birch.relay.mailchannels.net ([23.83.209.29]:2990) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hyMqD-0000BX-VL for 35564@debbugs.gnu.org; Thu, 15 Aug 2019 16:59:26 -0400 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 9760C1A277A; Thu, 15 Aug 2019 20:59:24 +0000 (UTC) Received: from pdx1-sub0-mail-a66.g.dreamhost.com (100-96-148-147.trex.outbound.svc.cluster.local [100.96.148.147]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 053821A1E95; Thu, 15 Aug 2019 20:59:24 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from pdx1-sub0-mail-a66.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.17.5); Thu, 15 Aug 2019 20:59:24 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Soft-Vacuous: 0be2d29d39282296_1565902764320_1065569905 X-MC-Loop-Signature: 1565902764320:2567480969 X-MC-Ingress-Time: 1565902764320 Received: from pdx1-sub0-mail-a66.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a66.g.dreamhost.com (Postfix) with ESMTP id 86F4684B5E; Thu, 15 Aug 2019 13:59:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; s=linkov.net; bh=1DtOZq JaK0dNBXzPLmcF3V64CnE=; b=VM6SJy3k70L1tDAR7IHvDcDu+sjIoD3/l4r27W pPP11X6o8qCZBEyXMHZzvygjSJJJO6A3g8e7txq8hW1hBanyu1vNwfuUDQTZeyig lqwSDxcLzoZZRMsvzj/4g6oKU80alOmWjnDu6Bcc65c8hd65pIDJ99XuEuK5o+cu gSTu0= Received: from mail.jurta.org (m91-129-109-163.cust.tele2.ee [91.129.109.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a66.g.dreamhost.com (Postfix) with ESMTPSA id 084FC84B4F; Thu, 15 Aug 2019 13:59:14 -0700 (PDT) X-DH-BACKEND: pdx1-sub0-mail-a66 From: Juri Linkov To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters Organization: LINKOV.NET References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> <87wog3pewu.fsf@gmail.com> <87v9vndsnj.fsf@web.de> <87imrl4ixr.fsf@web.de> <87r2688y1l.fsf@gmail.com> <87sgqkjfxv.fsf@web.de> <87tvas2b5o.fsf@gmail.com> <87d0hffjda.fsf@mail.linkov.net> <87k1bmfr1b.fsf@gmail.com> Date: Thu, 15 Aug 2019 23:56:23 +0300 In-Reply-To: <87k1bmfr1b.fsf@gmail.com> (=?iso-8859-1?Q?=22K=E9vin?= Le Gouguec"'s message of "Fri, 09 Aug 2019 14:43:12 +0200") Message-ID: <87mugajgg8.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 X-VR-OUT-STATUS: OK X-VR-OUT-SCORE: -100 X-VR-OUT-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeduvddrudefuddgudehgecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucggtfgfnhhsuhgsshgtrhhisggvpdfftffgtefojffquffvnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvffuohhfffgjkfgfgggtgfesthekredttderjeenucfhrhhomheplfhurhhiucfnihhnkhhovhcuoehjuhhriheslhhinhhkohhvrdhnvghtqeenucfkphepledurdduvdelrddutdelrdduieefnecurfgrrhgrmhepmhhouggvpehsmhhtphdphhgvlhhopehmrghilhdrjhhurhhtrgdrohhrghdpihhnvghtpeeluddruddvledruddtledrudeifedprhgvthhurhhnqdhprghthheplfhurhhiucfnihhnkhhovhcuoehjuhhriheslhhinhhkohhvrdhnvghtqedpmhgrihhlfhhrohhmpehjuhhriheslhhinhhkohhvrdhnvghtpdhnrhgtphhtthhopehkvghvihhnrdhlvghgohhughhuvggtsehgmhgrihhlrdgtohhmnecuvehluhhsthgvrhfuihiivgeptd Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > IIUC, your suggested prompt does not match what dired-do-shell-command > actually does: the function only ever substitutes '?' if it is > "isolated", i.e. surrounded with whitespace or backquotes. Cf. the > docstring: > >> =E2=80=98*=E2=80=99 and =E2=80=98?=E2=80=99 when not surrounded by whi= tespace nor =E2=80=98`=E2=80=99 have no special >> significance for =E2=80=98dired-do-shell-command=E2=80=99, and are pas= sed through >> normally to the shell, but you must confirm first. I collected a short summary that shows one case is still missing (=E2=80=98!=E2=80=99 means Dired prompt called on the marked file, and =E2=80=98$=E2=80=99 is the corresponding shell command): 1. ? ! cat ? $ cat marked ! cat ./? Confirm--do you mean to use =E2=80=98?=E2=80=99 as a wildcard? (y or = n) y $ cat ./? marked ! cat ?"" Confirm--do you mean to use =E2=80=98?=E2=80=99 as a wildcard? (y or = n) y $ cat ? marked ! cat '?' Confirm--do you mean to use =E2=80=98?=E2=80=99 as a wildcard? (y or = n) y $ cat '?' marked cat: '?': No such file or directory ! cat ./`?` $ cat ./marked 2. * ! cat * $ cat marked ! cat ./* Confirm--do you mean to use =E2=80=98*=E2=80=99 as a wildcard? (y or = n) y $ cat ./* marked ! cat *"" Confirm--do you mean to use =E2=80=98*=E2=80=99 as a wildcard? (y or = n) y $ cat * marked ! cat '*' Confirm--do you mean to use =E2=80=98*=E2=80=99 as a wildcard? (y or = n) y $ cat '*' marked cat: '*': No such file or directory Now the missing case - how to do the same that =E2=80=98cat ./`?`=E2=80=99= does, i.e. how to substitute =E2=80=98*=E2=80=99 by marked files in such Dired = prompt: ! cat ./`*` Confirm--do you mean to use =E2=80=98*=E2=80=99 as a wildcard? (y or = n) y $ cat ./`*` marked /bin/bash: marked: command not found cat: ./: Is a directory Why can't it run this shell command: $ cat ./marked From debbugs-submit-bounces@debbugs.gnu.org Mon Aug 19 00:55:42 2019 Received: (at 35564) by debbugs.gnu.org; 19 Aug 2019 04:55:42 +0000 Received: from localhost ([127.0.0.1]:59053 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hzZhl-0000Ot-PZ for submit@debbugs.gnu.org; Mon, 19 Aug 2019 00:55:41 -0400 Received: from mail-wr1-f43.google.com ([209.85.221.43]:46744) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hzZhk-0000Og-0j for 35564@debbugs.gnu.org; Mon, 19 Aug 2019 00:55:40 -0400 Received: by mail-wr1-f43.google.com with SMTP id z1so7202304wru.13 for <35564@debbugs.gnu.org>; Sun, 18 Aug 2019 21:55:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=18SxVqew43C9g9VKvCkbua9VtoNgRRld09X2sGDQ03A=; b=kemCrht2EBQ3ULpu6tR1Vc4TYyf55gwW8o6FYnGu4VZZMur5OY8Dz+2jI7NxD+d+hH z0GNr1Jl53tFDlwTzW3BydM1PxXEYJS39mgDAw2UG0GzPdNXw0cbSySAcylcytZxkbZ4 SGhMFlQXMltm9IbkxWKv14rLWkizU6LQ0apPFq7oawgiiDYuelgXnYcClw48eD5fgVQN ET5Ioanqq9dwjNxfEzgLcubXBMY/9vJ/PJawJZsiopaqdlOoG3Vow5KBVybCgdhvS4Gs kpLeKHs0QB1yDJZTiHLqOrsM4mkPGuJ7XoHzfmj0FbTpsBmSaml4gtXglanitbKG4h3X Y/lA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=18SxVqew43C9g9VKvCkbua9VtoNgRRld09X2sGDQ03A=; b=NTLDnATCmulvhrV5DMTEobXGZ54DRterjvRxn7q7wcHGl4AiVKdjt1PLu08+FzkUex 5OZZVw15RfAaJXw9IxjmeNZAPP3Su9oOiTl85dRfsa/rSu9RW+2GXD2vOk1eAx17Yaf8 CSfnORoRX5rOe2XCsVsbZdlO06WwQw2lzx42hcj/W53HxeWg6jryyc/J8buavxZkm7Gj jAUmHWreoB24kNiTCCD7fvEKEd4u78bXiTCBfx7GMzI1EJ/LkMyWkHCuDSMJtQDPVOSM OGzrbPxUHnBTe6kWc5n7b3INwlVzYmLsfLgaLID3HDnyC5s2+YDmQDFhssmWr1p6vcf7 6mvQ== X-Gm-Message-State: APjAAAVM//BGhuE9LRZnlWdM4aUnTKplTHREWQ5WDhs9XX7oyWty0wXj y494ucnw0C2VRDdFDiDQwGs= X-Google-Smtp-Source: APXvYqzV/NhOgXLYgWnzd7YACuiAJZ+wrSgL0Yqrw1Co8KcTFeIe+kFjaOtJkrJfBu0ixGrL1T8C6Q== X-Received: by 2002:a5d:5591:: with SMTP id i17mr24225552wrv.280.1566190534196; Sun, 18 Aug 2019 21:55:34 -0700 (PDT) Received: from nc10-laptop ([109.190.253.11]) by smtp.gmail.com with ESMTPSA id t14sm10889336wrv.12.2019.08.18.21.55.32 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 18 Aug 2019 21:55:33 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Juri Linkov Subject: Re: bug#35564: [PATCH v4] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87y313z3tp.fsf@gmail.com> <83wog3lo5c.fsf@gnu.org> <87wog3pewu.fsf@gmail.com> <87v9vndsnj.fsf@web.de> <87imrl4ixr.fsf@web.de> <87r2688y1l.fsf@gmail.com> <87sgqkjfxv.fsf@web.de> <87tvas2b5o.fsf@gmail.com> <87d0hffjda.fsf@mail.linkov.net> <87k1bmfr1b.fsf@gmail.com> <87mugajgg8.fsf@mail.linkov.net> Date: Mon, 19 Aug 2019 06:55:28 +0200 In-Reply-To: <87mugajgg8.fsf@mail.linkov.net> (Juri Linkov's message of "Thu, 15 Aug 2019 23:56:23 +0300") Message-ID: <87wof9u533.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, monnier@iro.umontreal.ca, npostavs@gmail.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Juri Linkov writes: > Now the missing case - how to do the same that =E2=80=98cat ./`?`=E2=80= =99 does, > i.e. how to substitute =E2=80=98*=E2=80=99 by marked files in such Dired = prompt: > > ! cat ./`*` > Confirm--do you mean to use =E2=80=98*=E2=80=99 as a wildcard? (y or = n) y > $ cat ./`*` marked > /bin/bash: marked: command not found > cat: ./: Is a directory > > Why can't it run this shell command: > > $ cat ./marked AFAICT, because dired--star-or-qmark-p does not handle `*`: > Isolated means that MATCH is surrounded by spaces or at the beginning/end > of STRING followed/prefixed with an space. A match to =E2=80=98`?`=E2=80= =99, > isolated or not, is also valid. I've skimmed the docstrings and comments for dired--star-or-qmark-p, dired-shell-stuff-it and dired-do-shell-command, but I could not find a rationale for not handling that case. git log -G'`\*`' hasn't finished yet but so far it hasn't told me anything either. If this is something we want[1], we can add it independently of this bug report. If no-one has committed it (or created a new bug report for it) by the time I get back to coding, I might throw in a patch for that in the series; chances are it might simplify the code somewhat, since ? and * will then be handled similarly. Thanks for the survey Juri! [1] I see no reason not to support it, since otherwise the shell translates `*` into the command first-file-according-to-locale other-files=E2=80=A6 which doesn't strike me as very useful behaviour. Substituting `*` for the file list, like we substitute `?` for each file, could make sense, e.g. for ! some-command "`*`" where some-command wants a space-separated file list as a single argument (though I can't come up with an actual command off the top of my head). From debbugs-submit-bounces@debbugs.gnu.org Thu Oct 10 14:45:34 2019 Received: (at 35564) by debbugs.gnu.org; 10 Oct 2019 18:45:34 +0000 Received: from localhost ([127.0.0.1]:57141 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iIdRL-0008NT-34 for submit@debbugs.gnu.org; Thu, 10 Oct 2019 14:45:34 -0400 Received: from mail-wr1-f51.google.com ([209.85.221.51]:38828) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iIdRE-0008My-Kn; Thu, 10 Oct 2019 14:45:26 -0400 Received: by mail-wr1-f51.google.com with SMTP id w12so9127645wro.5; Thu, 10 Oct 2019 11:45:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=LVRBztbo5TPq2dk6MGtV1MQvuQ0wgV7rFB1h47DB6aQ=; b=XZPvwe44Mb2yJzd7g5ofYcHfJWMIYo1Pg79F0vp4IbiM8adxzxxyZ02cp4jKJdMVZE f9/xrKXYmLTHM8tIQFnTMl+hLN0cQpFFYby5+NsGyzUmlFL2YcVb3DPcAWKfuKJO5HXt zL/Wf294IaeSLBa489l1/svtPp2+f9MJDAS3MJfHgaB0EnPlas0lpgtW6YF6CbhDTNMr eoEiQDa60qSkBFj+Y6I5HPJ/EhwKJjVq9XyIHta74RtS5HU3gImJ5o00wQzxVe5m3EFV a2pNMo8wJDByDG0UlS7xzqAKXVqL2Cg0fspS369hWQuMOvbJHxfnnHMgzQqPC0Cml3vA 8m9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=LVRBztbo5TPq2dk6MGtV1MQvuQ0wgV7rFB1h47DB6aQ=; b=iCs1wBN/+qIdyWL6WbabTas5fw9Ub7/SAx8aUm1tEBku04u835FlVcDrwroW4AWHK+ Qedg4tbE4qQ01gTauICJ8a9NFFwKyPLd5jm0U0b+OBfH/eA03kn3B0tvt0QKjB47mZrr B8ZuEWTJf8tuHehO+7Z+KReIiQfrNCcm3bcYsWBj86hYez0gAyxAdO1hJm8iwOhco5mv o4sNFvCiLufBM95Ntd23VDVxPM+jPknGgSOfrmwktBzuZIlot9yBFUlINsjnAyafPPMT +GUFMv8XLHnYvUMMTyRxBUaKVFgb0n/5tp0UIYBSDy/Of4fTiSFaQYhdKJXGMO8tax6q K/4Q== X-Gm-Message-State: APjAAAV6sxpkvOu7nFCGHRvLK/TPiAAwimXsYk9d3ztFBpsyWQ9ZXE06 sIIlLEnAUjia5MWu5uyeRFs= X-Google-Smtp-Source: APXvYqw+rBf/HmYmTA7nG0Dgn7aEcJOgZUHttQRc09fB9HAnYp2wQPlLKBRNUJ8s8MEYJ9+a1FYB/Q== X-Received: by 2002:adf:f18a:: with SMTP id h10mr9503634wro.145.1570733118759; Thu, 10 Oct 2019 11:45:18 -0700 (PDT) Received: from my-little-tumbleweed (71.142.13.109.rev.sfr.net. [109.13.142.71]) by smtp.gmail.com with ESMTPSA id m18sm9066657wrg.97.2019.10.10.11.45.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Oct 2019 11:45:17 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: 35564@debbugs.gnu.org Subject: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> Date: Thu, 10 Oct 2019 20:45:14 +0200 In-Reply-To: <87imsinbmr.fsf_-_@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Wed, 03 Jul 2019 21:47:40 +0200") Message-ID: <87o8yoign9.fsf_-_@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , Noam Postavsky , Juri Linkov , Stefan Monnier , Eli Zaretskii , 28969@debbugs.gnu.org, Drew Adams X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Finally got around to try out rmc.el. A brief recap of the issue: dired-do-shell-command looks out for any non-isolated metacharacters[1], and prompts the user when it finds some. The problem is that the prompt is downright misleading under some circumstances. E.g. after marking some files in a Dired buffer: ! sed 's/?/!/g' RET => Confirm--do you mean to use `?' as a wildcard? The answer a user must input to proceed is "yes", despite '?' not being a wildcard in this situation; the answer some users may give intuitively is "no" (or, in my case, "whaaa?"). This patch series initially tried to shove the command in the prompt, highlight the non-isolated characters, and re-phrase the prompt to be more accurate (i.e. not talk about wildcards). It went through a several iterations for a few reasons[2]; most recently Michael suggested using read-multiple-choice [bug#35564#136]; I looked at how nsm.el uses it, saw that is was good, and got distracted for two months. Here is the new series: --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Tweak-dired-warning-about-wildcard-characters.patch >From 0c0b1570623a69141ebd31b8e3dffdeef5273c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:19:44 +0200 Subject: [PATCH 1/5] Tweak dired warning about "wildcard" characters Non-isolated '?' and '*' characters may be quoted, or backslash-escaped; we do not know for a fact that the shell will interpret them as wildcards. Rephrase the prompt and highlight the characters so that the user sees exactly what we are talking about. * lisp/dired-aux.el (dired--isolated-char-p) (dired--highlight-nosubst-char, dired--no-subst-prompt): New functions. (dired-do-shell-command): Use them. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p) (dired-test-highlight-metachar): Test the new functions. (Bug#35564) --- lisp/dired-aux.el | 42 ++++++++++++++++++++++++++++++++---- test/lisp/dired-aux-tests.el | 28 ++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index bfc37c5cde..409f028e2b 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -79,6 +79,42 @@ dired--star-or-qmark-p (funcall (if keep #'string-match-p #'string-match) x string)) regexps))) +(defun dired--isolated-char-p (command pos) + "Assert whether the character at POS is isolated within COMMAND. +A character is isolated if: +- it is surrounded by whitespace, the start of the command, or + the end of the command, +- it is surrounded by `\\=`' characters." + (let ((start (max 0 (1- pos))) + (char (string (aref command pos)))) + (and (string-match + (rx (or (seq (or bos blank) + (group-n 1 (literal char)) + (or eos blank)) + (seq ?` (group-n 1 (literal char)) ?`))) + command start) + (= pos (match-beginning 1))))) + +(defun dired--highlight-nosubst-char (command char) + "Highlight occurences of CHAR that are not isolated in COMMAND. +These occurences will not be substituted; they will be sent as-is +to the shell, which may interpret them as wildcards." + (save-match-data + (let ((highlighted (substring-no-properties command)) + (pos 0)) + (while (string-match (regexp-quote char) command pos) + (let ((start (match-beginning 0)) + (end (match-end 0))) + (unless (dired--isolated-char-p command start) + (add-face-text-property start end 'warning nil highlighted)) + (setq pos end))) + highlighted))) + +(defun dired--no-subst-prompt (command char) + (let ((highlighted-command (dired--highlight-nosubst-char command char)) + (prompt "Confirm--the highlighted characters will not be substituted:")) + (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + ;;;###autoload (defun dired-diff (file &optional switches) "Compare file at point with FILE using `diff'. @@ -761,11 +797,9 @@ dired-do-shell-command (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((need-confirm-p command "*") - (y-or-n-p (format-message - "Confirm--do you mean to use `*' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "*"))) ((need-confirm-p command "?") - (y-or-n-p (format-message - "Confirm--do you mean to use `?' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "?"))) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ccd3192792..80b6393931 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,6 +114,34 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(ert-deftest dired-test-isolated-char-p () + (should (dired--isolated-char-p "?" 0)) + (should (dired--isolated-char-p "? " 0)) + (should (dired--isolated-char-p " ?" 1)) + (should (dired--isolated-char-p " ? " 1)) + (should (dired--isolated-char-p "foo bar ? baz" 8)) + (should (dired--isolated-char-p "foo -i`?`" 7)) + (should-not (dired--isolated-char-p "foo `bar`?" 9)) + (should-not (dired--isolated-char-p "foo 'bar?'" 8)) + (should-not (dired--isolated-char-p "foo bar?baz" 7)) + (should-not (dired--isolated-char-p "foo bar?" 7))) + +(ert-deftest dired-test-highlight-metachar () + "Check that non-isolated meta-characters are highlighted" + (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (result (dired--highlight-nosubst-char command "?"))) + (should-not (text-property-not-all 1 14 'face nil result)) + (should (equal 'warning (get-text-property 15 'face result))) + (should-not (text-property-not-all 16 28 'face nil result)) + (should (equal 'warning (get-text-property 29 'face result))) + (should-not (text-property-not-all 30 39 'face nil result))) + (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") + (result (dired--highlight-nosubst-char command "*"))) + (should-not (text-property-not-all 1 10 'face nil result)) + (should (equal 'warning (get-text-property 11 'face result))) + (should-not (text-property-not-all 12 23 'face nil result)) + (should (equal 'warning (get-text-property 24 'face result))) + (should-not (text-property-not-all 25 29 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.23.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-Dedup-dired-aux-isolated-char-searching-Bug-35564.patch >From b80d55bf5307cf95ae0804cc1dfe66b40b012ba6 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 27 Jun 2019 19:15:56 -0400 Subject: [PATCH 2/5] Dedup dired-aux isolated char searching (Bug#35564) * lisp/dired-aux.el (dired-isolated-string-re): Use explicitly numbered groups. (dired--star-or-qmark-p): Add START parameter. Make sure to return the first isolated match. (dired--no-subst-prompt): Operate on a list of positions rather than searching again for isolated chars. Shorten prompt, and include the character being asked about in the question (to make it clearer, and in case the user can't see the fontification for whatever reason, e.g., screen reader). (dired--isolated-char-p): Remove. (dired--need-confirm-positions): New function. (dired-do-shell-command): Use it. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p): Remove. (dired-test-highlight-metachar): Adjust to new functions. Make sure that `*` isn't considered isolated. --- lisp/dired-aux.el | 113 ++++++++++++++++------------------- test/lisp/dired-aux-tests.el | 31 +++++----- 2 files changed, 67 insertions(+), 77 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 409f028e2b..c13cbcf2e3 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -60,60 +60,60 @@ dired-isolated-string-re of a string followed/prefixed with an space. The regexp capture the preceding blank, STRING and the following blank as the groups 1, 2 and 3 respectively." - (format "\\(\\`\\|[ \t]\\)\\(%s\\)\\([ \t]\\|\\'\\)" string)) + (format "\\(?1:\\`\\|[ \t]\\)\\(?2:%s\\)\\(?3:[ \t]\\|\\'\\)" string)) -(defun dired--star-or-qmark-p (string match &optional keep) +(defun dired--star-or-qmark-p (string match &optional keep start) "Return non-nil if STRING contains isolated MATCH or `\\=`?\\=`'. MATCH should be the strings \"?\", `\\=`?\\=`', \"*\" or nil. The latter means STRING contains either \"?\" or `\\=`?\\=`' or \"*\". If optional arg KEEP is non-nil, then preserve the match data. Otherwise, this function changes it and saves MATCH as the second match group. +START is the position to start matching from. Isolated means that MATCH is surrounded by spaces or at the beginning/end of STRING followed/prefixed with an space. A match to `\\=`?\\=`', isolated or not, is also valid." - (let ((regexps (list (dired-isolated-string-re (if match (regexp-quote match) "[*?]"))))) + (let ((regexp (dired-isolated-string-re (if match (regexp-quote match) "[*?]")))) (when (or (null match) (equal match "?")) - (setq regexps (append (list "\\(\\)\\(`\\?`\\)\\(\\)") regexps))) - (cl-some (lambda (x) - (funcall (if keep #'string-match-p #'string-match) x string)) - regexps))) - -(defun dired--isolated-char-p (command pos) - "Assert whether the character at POS is isolated within COMMAND. -A character is isolated if: -- it is surrounded by whitespace, the start of the command, or - the end of the command, -- it is surrounded by `\\=`' characters." - (let ((start (max 0 (1- pos))) - (char (string (aref command pos)))) - (and (string-match - (rx (or (seq (or bos blank) - (group-n 1 (literal char)) - (or eos blank)) - (seq ?` (group-n 1 (literal char)) ?`))) - command start) - (= pos (match-beginning 1))))) - -(defun dired--highlight-nosubst-char (command char) - "Highlight occurences of CHAR that are not isolated in COMMAND. -These occurences will not be substituted; they will be sent as-is -to the shell, which may interpret them as wildcards." - (save-match-data - (let ((highlighted (substring-no-properties command)) - (pos 0)) - (while (string-match (regexp-quote char) command pos) - (let ((start (match-beginning 0)) - (end (match-end 0))) - (unless (dired--isolated-char-p command start) - (add-face-text-property start end 'warning nil highlighted)) - (setq pos end))) - highlighted))) - -(defun dired--no-subst-prompt (command char) - (let ((highlighted-command (dired--highlight-nosubst-char command char)) - (prompt "Confirm--the highlighted characters will not be substituted:")) - (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + (cl-callf concat regexp "\\|\\(?1:\\)\\(?2:`\\?`\\)\\(?3:\\)")) + (funcall (if keep #'string-match-p #'string-match) regexp string start))) + +(defun dired--need-confirm-positions (command string) + "Search for non-isolated matches of STRING in COMMAND. +Return a list of positions that match STRING, but would not be +considered \"isolated\" by `dired--star-or-qmark-p'." + (cl-assert (= (length string) 1)) + (let ((start 0) + (isolated-char-positions nil) + (confirm-positions nil) + (regexp (regexp-quote string))) + ;; Collect all ? and * surrounded by spaces and `?`. + (while (dired--star-or-qmark-p command string nil start) + (push (cons (match-beginning 2) (match-end 2)) + isolated-char-positions) + (setq start (match-end 2))) + ;; Now collect any remaining ? and *. + (setq start 0) + (while (string-match regexp command start) + (unless (cl-member (match-beginning 0) isolated-char-positions + :test (lambda (pos match) + (<= (car match) pos (cdr match)))) + (push (match-beginning 0) confirm-positions)) + (setq start (match-end 0))) + confirm-positions)) + +(defun dired--no-subst-prompt (char-positions command) + (cl-callf substring-no-properties command) + (dolist (pos char-positions) + (add-face-text-property pos (1+ pos) 'warning nil command)) + (concat command "\n" + (format-message + (ngettext "Send %d occurrence of `%s' as-is to shell?" + "Send %d occurrences of `%s' as-is to shell?" + (length char-positions)) + (length char-positions) + (propertize (string (aref command (car char-positions))) + 'face 'warning)))) ;;;###autoload (defun dired-diff (file &optional switches) @@ -781,26 +781,19 @@ dired-do-shell-command (dired-read-shell-command "! on %s: " current-prefix-arg files) current-prefix-arg files))) - (cl-flet ((need-confirm-p - (cmd str) - (let ((res cmd) - (regexp (regexp-quote str))) - ;; Drop all ? and * surrounded by spaces and `?`. - (while (and (string-match regexp res) - (dired--star-or-qmark-p res str)) - (setq res (replace-match "" t t res 2))) - (string-match regexp res)))) (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) + (confirmations nil) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. - (ok (cond ((not (or on-each no-subst)) - (error "You can not combine `*' and `?' substitution marks")) - ((need-confirm-p command "*") - (y-or-n-p (dired--no-subst-prompt command "*"))) - ((need-confirm-p command "?") - (y-or-n-p (dired--no-subst-prompt command "?"))) - (t)))) + (ok (cond + ((not (or on-each no-subst)) + (error "You can not combine `*' and `?' substitution marks")) + ((setq confirmations (dired--need-confirm-positions command "*")) + (y-or-n-p (dired--no-subst-prompt confirmations command))) + ((setq confirmations (dired--need-confirm-positions command "?")) + (y-or-n-p (dired--no-subst-prompt confirmations command))) + (t)))) (cond ((not ok) (message "Command canceled")) (t (if on-each @@ -811,7 +804,7 @@ dired-do-shell-command nil file-list) ;; execute the shell command (dired-run-shell-command - (dired-shell-stuff-it command file-list nil arg)))))))) + (dired-shell-stuff-it command file-list nil arg))))))) ;; Might use {,} for bash or csh: (defvar dired-mark-prefix "" diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 80b6393931..ff18edddb6 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,34 +114,31 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) -(ert-deftest dired-test-isolated-char-p () - (should (dired--isolated-char-p "?" 0)) - (should (dired--isolated-char-p "? " 0)) - (should (dired--isolated-char-p " ?" 1)) - (should (dired--isolated-char-p " ? " 1)) - (should (dired--isolated-char-p "foo bar ? baz" 8)) - (should (dired--isolated-char-p "foo -i`?`" 7)) - (should-not (dired--isolated-char-p "foo `bar`?" 9)) - (should-not (dired--isolated-char-p "foo 'bar?'" 8)) - (should-not (dired--isolated-char-p "foo bar?baz" 7)) - (should-not (dired--isolated-char-p "foo bar?" 7))) - (ert-deftest dired-test-highlight-metachar () "Check that non-isolated meta-characters are highlighted" (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") - (result (dired--highlight-nosubst-char command "?"))) + (prompt (dired--no-subst-prompt + (dired--need-confirm-positions command "?") + command)) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 14 'face nil result)) (should (equal 'warning (get-text-property 15 'face result))) (should-not (text-property-not-all 16 28 'face nil result)) (should (equal 'warning (get-text-property 29 'face result))) (should-not (text-property-not-all 30 39 'face nil result))) - (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") - (result (dired--highlight-nosubst-char command "*"))) + ;; Note that `?` is considered isolated, but `*` is not. + (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (prompt (dired--no-subst-prompt + (dired--need-confirm-positions command "*") + command)) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 10 'face nil result)) (should (equal 'warning (get-text-property 11 'face result))) (should-not (text-property-not-all 12 23 'face nil result)) - (should (equal 'warning (get-text-property 24 'face result))) - (should-not (text-property-not-all 25 29 'face nil result)))) + (should (equal 'warning (get-text-property 25 'face result))) + (should-not (text-property-not-all 26 32 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.23.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0003-Add-markers-below-non-isolated-chars-in-dired-prompt.patch >From cd41c96d0631275d1fc24367663cf891a17cad47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 3 Jul 2019 21:17:57 +0200 Subject: [PATCH 3/5] Add '^' markers below non-isolated chars in dired prompt * lisp/dired-aux.el (dired--mark-positions): New function. (dired--no-subst-prompt): Use it to show chars without overly relying on highlighting. (dired-do-shell-command): When the echo area is wide enough to display the command without wrapping it, add the markers. * test/lisp/dired-aux-tests.el (dired-test-highlight-metachar): Add assertion for '^' marker positions. (Bug#35564) --- lisp/dired-aux.el | 43 +++++++++++++++++++++-------- test/lisp/dired-aux-tests.el | 53 ++++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 28 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index c13cbcf2e3..01c1b92595 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -102,18 +102,35 @@ dired--need-confirm-positions (setq start (match-end 0))) confirm-positions)) -(defun dired--no-subst-prompt (char-positions command) +(defun dired--mark-positions (positions) + (let ((markers (make-string + (1+ (apply #'max positions)) + ?\s))) + (dolist (pos positions) + (setf (aref markers pos) ?^)) + markers)) + +(defun dired--no-subst-prompt (char-positions command add-markers) (cl-callf substring-no-properties command) (dolist (pos char-positions) (add-face-text-property pos (1+ pos) 'warning nil command)) - (concat command "\n" - (format-message - (ngettext "Send %d occurrence of `%s' as-is to shell?" - "Send %d occurrences of `%s' as-is to shell?" - (length char-positions)) - (length char-positions) - (propertize (string (aref command (car char-positions))) - 'face 'warning)))) + ;; `y-or-n-p' adds some text to the beginning of the prompt when the + ;; user fails to answer 'y' or 'n'. The highlighted command thus + ;; cannot be put on the first line of the prompt, since the added + ;; text will shove the command to the right, and the '^' markers + ;; will become misaligned. + (apply #'concat + `("Confirm:\n" + ,command "\n" + ,@(when add-markers + (list (dired--mark-positions char-positions) "\n")) + ,(format-message + (ngettext "Send %d occurrence of `%s' as-is to shell?" + "Send %d occurrences of `%s' as-is to shell?" + (length char-positions)) + (length char-positions) + (propertize (string (aref command (car char-positions))) + 'face 'warning))))) ;;;###autoload (defun dired-diff (file &optional switches) @@ -784,15 +801,19 @@ dired-do-shell-command (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) (confirmations nil) + (short-enough (< (length command) + (window-width (minibuffer-window)))) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((setq confirmations (dired--need-confirm-positions command "*")) - (y-or-n-p (dired--no-subst-prompt confirmations command))) + (y-or-n-p (dired--no-subst-prompt confirmations command + short-enough))) ((setq confirmations (dired--need-confirm-positions command "?")) - (y-or-n-p (dired--no-subst-prompt confirmations command))) + (y-or-n-p (dired--no-subst-prompt confirmations command + short-enough))) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ff18edddb6..174c27052e 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -115,30 +115,49 @@ dired-test-bug30624 (kill-buffer buf))))) (ert-deftest dired-test-highlight-metachar () - "Check that non-isolated meta-characters are highlighted" + "Check that non-isolated meta-characters are highlighted." (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (markers " ^ ^") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "?") - command)) - (result (and (string-match (regexp-quote command) prompt) - (match-string 0 prompt)))) - (should-not (text-property-not-all 1 14 'face nil result)) - (should (equal 'warning (get-text-property 15 'face result))) - (should-not (text-property-not-all 16 28 'face nil result)) - (should (equal 'warning (get-text-property 29 'face result))) - (should-not (text-property-not-all 30 39 'face nil result))) + command + t)) + (lines (split-string prompt "\n")) + (highlit-command (nth 1 lines))) + (should (= (length lines) 4)) + (should (string-match (regexp-quote command) highlit-command)) + (should (string-match (regexp-quote markers) (nth 2 lines))) + (should-not (text-property-not-all 1 14 'face nil highlit-command)) + (should (equal 'warning (get-text-property 15 'face highlit-command))) + (should-not (text-property-not-all 16 28 'face nil highlit-command)) + (should (equal 'warning (get-text-property 29 'face highlit-command))) + (should-not (text-property-not-all 30 39 'face nil highlit-command))) ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (markers " ^ ^") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "*") - command)) - (result (and (string-match (regexp-quote command) prompt) - (match-string 0 prompt)))) - (should-not (text-property-not-all 1 10 'face nil result)) - (should (equal 'warning (get-text-property 11 'face result))) - (should-not (text-property-not-all 12 23 'face nil result)) - (should (equal 'warning (get-text-property 25 'face result))) - (should-not (text-property-not-all 26 32 'face nil result)))) + command + t)) + (lines (split-string prompt "\n")) + (highlit-command (nth 1 lines))) + (should (= (length lines) 4)) + (should (string-match (regexp-quote command) highlit-command)) + (should (string-match (regexp-quote markers) (nth 2 lines))) + (should-not (text-property-not-all 1 10 'face nil highlit-command)) + (should (equal 'warning (get-text-property 11 'face highlit-command))) + (should-not (text-property-not-all 12 23 'face nil highlit-command)) + (should (equal 'warning (get-text-property 25 'face highlit-command))) + (should-not (text-property-not-all 26 32 'face nil highlit-command))) + (let* ((command "sed 's/\\?/!/'") + (prompt (dired--no-subst-prompt + (dired--need-confirm-positions command "?") + command + nil)) + (lines (split-string prompt "\n")) + (highlit-command (nth 1 lines))) + (should (= (length lines) 3)) + (should (string-match (regexp-quote command) highlit-command)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.23.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0004-Simplify-highlighting-assertions.patch >From 7a884e189fa18cd903c6c684090860cf8ebb7f7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 12 Jul 2019 16:10:54 +0200 Subject: [PATCH 4/5] Simplify highlighting assertions * test/lisp/dired-aux-tests.el (dired-test--check-highlighting): New function. (dired-test-highlight-metachar): Use it. (Bug#35564) --- test/lisp/dired-aux-tests.el | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 174c27052e..ba10c54332 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,6 +114,15 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(defun dired-test--check-highlighting (command positions) + (let ((start 1)) + (dolist (pos positions) + (should-not (text-property-not-all start (1- pos) 'face nil command)) + (should (equal 'warning (get-text-property pos 'face command))) + (setq start (1+ pos))) + (should-not (text-property-not-all + start (length command) 'face nil command)))) + (ert-deftest dired-test-highlight-metachar () "Check that non-isolated meta-characters are highlighted." (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") @@ -127,11 +136,7 @@ dired-test-highlight-metachar (should (= (length lines) 4)) (should (string-match (regexp-quote command) highlit-command)) (should (string-match (regexp-quote markers) (nth 2 lines))) - (should-not (text-property-not-all 1 14 'face nil highlit-command)) - (should (equal 'warning (get-text-property 15 'face highlit-command))) - (should-not (text-property-not-all 16 28 'face nil highlit-command)) - (should (equal 'warning (get-text-property 29 'face highlit-command))) - (should-not (text-property-not-all 30 39 'face nil highlit-command))) + (dired-test--check-highlighting highlit-command '(15 29))) ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") (markers " ^ ^") @@ -144,11 +149,7 @@ dired-test-highlight-metachar (should (= (length lines) 4)) (should (string-match (regexp-quote command) highlit-command)) (should (string-match (regexp-quote markers) (nth 2 lines))) - (should-not (text-property-not-all 1 10 'face nil highlit-command)) - (should (equal 'warning (get-text-property 11 'face highlit-command))) - (should-not (text-property-not-all 12 23 'face nil highlit-command)) - (should (equal 'warning (get-text-property 25 'face highlit-command))) - (should-not (text-property-not-all 26 32 'face nil highlit-command))) + (dired-test--check-highlighting highlit-command '(11 25))) (let* ((command "sed 's/\\?/!/'") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "?") @@ -157,7 +158,8 @@ dired-test-highlight-metachar (lines (split-string prompt "\n")) (highlit-command (nth 1 lines))) (should (= (length lines) 3)) - (should (string-match (regexp-quote command) highlit-command)))) + (should (string-match (regexp-quote command) highlit-command)) + (dired-test--check-highlighting highlit-command '(8)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.23.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0005-Hide-detailed-explanations-in-a-togglable-help-buffe.patch >From 9fa3a93492c6c4d6553cff163d0203253bdb2eb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 2 Oct 2019 22:04:01 +0200 Subject: [PATCH 5/5] Hide detailed explanations in a togglable help buffer * test/lisp/dired-aux-tests.el (dired-test-bug27496): (dired-test-highlight-metachar): Adapt to new prompt. * lisp/dired-aux.el (dired--no-subst-prompt): Split into... (dired--highlight-no-subst-chars): add warning face and possibly '^' markers to command, (dired--no-subst-explain): fill in help buffer with detailed explanations, (dired--no-subst-ask): setup read-multiple-choice, (dired--no-subst-confirm): loop until we know what to do. (dired-do-shell-command): Call new function 'dired--no-subst-confirm.' (bug#28969, bug#35564) --- lisp/dired-aux.el | 102 ++++++++++++++++++++++++++--------- test/lisp/dired-aux-tests.el | 39 +++++++------- 2 files changed, 95 insertions(+), 46 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 01c1b92595..6b33f4ebfb 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -110,27 +110,83 @@ dired--mark-positions (setf (aref markers pos) ?^)) markers)) -(defun dired--no-subst-prompt (char-positions command add-markers) +(defun dired--highlight-no-subst-chars (positions command mark) (cl-callf substring-no-properties command) - (dolist (pos char-positions) + (dolist (pos positions) (add-face-text-property pos (1+ pos) 'warning nil command)) - ;; `y-or-n-p' adds some text to the beginning of the prompt when the - ;; user fails to answer 'y' or 'n'. The highlighted command thus - ;; cannot be put on the first line of the prompt, since the added - ;; text will shove the command to the right, and the '^' markers - ;; will become misaligned. - (apply #'concat - `("Confirm:\n" - ,command "\n" - ,@(when add-markers - (list (dired--mark-positions char-positions) "\n")) - ,(format-message - (ngettext "Send %d occurrence of `%s' as-is to shell?" - "Send %d occurrences of `%s' as-is to shell?" - (length char-positions)) - (length char-positions) - (propertize (string (aref command (car char-positions))) - 'face 'warning))))) + (if mark + (concat command "\n" (dired--mark-positions positions)) + command)) + +(defun dired--no-subst-explain (buf char-positions command mark-positions) + (with-current-buffer buf + (erase-buffer) + (insert + (format-message "\ +If your command contains occurrences of `*' surrounded by +whitespace, `dired-do-shell-command' substitutes them for the +entire file list to process. Otherwise, if your command contains +occurrences of `?' surrounded by whitespace or `%s', Dired will +run the command once for each file, substituting `?' for each +file name. + +Your command contains occurrences of `%s' that will not be +substituted, and will be passed through normally to the shell. + +%s +" + "`" + (string (aref command (car char-positions))) + (dired--highlight-no-subst-chars char-positions command mark-positions))))) + +(defun dired--no-subst-ask (char nb-occur details) + (let ((hilit-char (propertize (string char) 'face 'warning))) + (car + (read-multiple-choice + (format-message + (ngettext + "Warning: %d occurrence of `%s' will not be substituted. Proceed?" + "Warning: %d occurrences of `%s' will not be substituted. Proceed?" + nb-occur) + nb-occur hilit-char) + `((?y "yes" "Send shell command without substituting.") + (?n "no" "Abort.") + (?d "toggle details" ,(format-message + "Show/hide occurrences of `%s'" hilit-char)) + ,@(when details + '((?m "toggle markers" "Show/hide `^' markers")))))))) + +(defun dired--no-subst-confirm (char-positions command) + (let ((help-buf (get-buffer-create "*Dired help*")) + (char (aref command (car char-positions))) + (nb-occur (length char-positions)) + (done nil) + (details nil) + (markers nil) + proceed) + (dired--no-subst-explain help-buf char-positions command nil) + (unwind-protect + (save-window-excursion + (while (not done) + (cl-case (dired--no-subst-ask char nb-occur details) + (?y + (setq done t + proceed t)) + (?n + (setq done t + proceed nil)) + (?d + (if details + (progn + (quit-window nil details) + (setq details nil)) + (setq details (display-buffer help-buf)))) + (?m + (setq markers (not markers)) + (dired--no-subst-explain + help-buf char-positions command markers))))) + (kill-buffer help-buf)) + proceed)) ;;;###autoload (defun dired-diff (file &optional switches) @@ -801,19 +857,15 @@ dired-do-shell-command (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) (confirmations nil) - (short-enough (< (length command) - (window-width (minibuffer-window)))) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((setq confirmations (dired--need-confirm-positions command "*")) - (y-or-n-p (dired--no-subst-prompt confirmations command - short-enough))) + (dired--no-subst-confirm confirmations command)) ((setq confirmations (dired--need-confirm-positions command "?")) - (y-or-n-p (dired--no-subst-prompt confirmations command - short-enough))) + (dired--no-subst-confirm confirmations command)) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ba10c54332..e1d9eefbea 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -28,7 +28,7 @@ dired-test-bug27496 (let* ((foo (make-temp-file "foo")) (files (list foo))) (unwind-protect - (cl-letf (((symbol-function 'y-or-n-p) 'error)) + (cl-letf (((symbol-function 'read-multiple-choice) 'error)) (dired temporary-file-directory) (dired-goto-file foo) ;; `dired-do-shell-command' returns nil on success. @@ -127,39 +127,36 @@ dired-test-highlight-metachar "Check that non-isolated meta-characters are highlighted." (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") (markers " ^ ^") - (prompt (dired--no-subst-prompt + (result (dired--highlight-no-subst-chars (dired--need-confirm-positions command "?") command t)) - (lines (split-string prompt "\n")) - (highlit-command (nth 1 lines))) - (should (= (length lines) 4)) - (should (string-match (regexp-quote command) highlit-command)) - (should (string-match (regexp-quote markers) (nth 2 lines))) - (dired-test--check-highlighting highlit-command '(15 29))) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(15 29))) ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") (markers " ^ ^") - (prompt (dired--no-subst-prompt + (result (dired--highlight-no-subst-chars (dired--need-confirm-positions command "*") command t)) - (lines (split-string prompt "\n")) - (highlit-command (nth 1 lines))) - (should (= (length lines) 4)) - (should (string-match (regexp-quote command) highlit-command)) - (should (string-match (regexp-quote markers) (nth 2 lines))) - (dired-test--check-highlighting highlit-command '(11 25))) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(11 25))) (let* ((command "sed 's/\\?/!/'") - (prompt (dired--no-subst-prompt + (result (dired--highlight-no-subst-chars (dired--need-confirm-positions command "?") command nil)) - (lines (split-string prompt "\n")) - (highlit-command (nth 1 lines))) - (should (= (length lines) 3)) - (should (string-match (regexp-quote command) highlit-command)) - (dired-test--check-highlighting highlit-command '(8)))) + (lines (split-string result "\n"))) + (should (= (length lines) 1)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (dired-test--check-highlighting (nth 0 lines) '(8)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.23.0 --=-=-= Content-Type: text/plain Highlights: - removed the patch for y-or-n-p, since we don't need it anymore, - (squashed Noam's patch with my fixups,) - the last patch contains the new stuff: - the default prompt is now as concise as the old one, - pressing 'd' toggles a help buffer which highlights occurrences using the warning face, - when the help buffer is enabled, pressing 'm' toggles the '^' markers. Squashed patch for convenience: --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Tweak-dired-warning-about-wildcard-characters.patch >From 8a51df696ef4d1b794ea75d94b1137f1e1ff536f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Thu, 10 Oct 2019 20:20:41 +0200 Subject: [PATCH] Tweak dired warning about "wildcard" characters Non-isolated '?' and '*' characters may be quoted, or backslash-escaped; we do not know for a fact that the shell will interpret them as wildcards. Rephrase the prompt and offer to highlight the characters so that the user sees exactly what we are talking about. * lisp/dired-aux.el (dired-isolated-string-re): Use explicitly numbered groups. (dired--star-or-qmark-p): Add START parameter. Make sure to return the first isolated match. (dired--need-confirm-positions, dired--mark-positions) (dired--highlight-no-subst-chars, dired--no-subst-explain) (dired--no-subst-ask, dired--no-subst-confirm): New functions. (dired-do-shell-command): Use them. * test/lisp/dired-aux-tests.el (dired-test-bug27496): Adapt to new prompt. (dired-test--check-highlighting): New test helper. (dired-test-highlight-metachar): New tests. Co-authored-by: Noam Postavsky (bug#28969, bug#35564) --- lisp/dired-aux.el | 152 +++++++++++++++++++++++++++++------ test/lisp/dired-aux-tests.el | 45 ++++++++++- 2 files changed, 170 insertions(+), 27 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index bfc37c5cde..6b33f4ebfb 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -60,24 +60,133 @@ dired-isolated-string-re of a string followed/prefixed with an space. The regexp capture the preceding blank, STRING and the following blank as the groups 1, 2 and 3 respectively." - (format "\\(\\`\\|[ \t]\\)\\(%s\\)\\([ \t]\\|\\'\\)" string)) + (format "\\(?1:\\`\\|[ \t]\\)\\(?2:%s\\)\\(?3:[ \t]\\|\\'\\)" string)) -(defun dired--star-or-qmark-p (string match &optional keep) +(defun dired--star-or-qmark-p (string match &optional keep start) "Return non-nil if STRING contains isolated MATCH or `\\=`?\\=`'. MATCH should be the strings \"?\", `\\=`?\\=`', \"*\" or nil. The latter means STRING contains either \"?\" or `\\=`?\\=`' or \"*\". If optional arg KEEP is non-nil, then preserve the match data. Otherwise, this function changes it and saves MATCH as the second match group. +START is the position to start matching from. Isolated means that MATCH is surrounded by spaces or at the beginning/end of STRING followed/prefixed with an space. A match to `\\=`?\\=`', isolated or not, is also valid." - (let ((regexps (list (dired-isolated-string-re (if match (regexp-quote match) "[*?]"))))) + (let ((regexp (dired-isolated-string-re (if match (regexp-quote match) "[*?]")))) (when (or (null match) (equal match "?")) - (setq regexps (append (list "\\(\\)\\(`\\?`\\)\\(\\)") regexps))) - (cl-some (lambda (x) - (funcall (if keep #'string-match-p #'string-match) x string)) - regexps))) + (cl-callf concat regexp "\\|\\(?1:\\)\\(?2:`\\?`\\)\\(?3:\\)")) + (funcall (if keep #'string-match-p #'string-match) regexp string start))) + +(defun dired--need-confirm-positions (command string) + "Search for non-isolated matches of STRING in COMMAND. +Return a list of positions that match STRING, but would not be +considered \"isolated\" by `dired--star-or-qmark-p'." + (cl-assert (= (length string) 1)) + (let ((start 0) + (isolated-char-positions nil) + (confirm-positions nil) + (regexp (regexp-quote string))) + ;; Collect all ? and * surrounded by spaces and `?`. + (while (dired--star-or-qmark-p command string nil start) + (push (cons (match-beginning 2) (match-end 2)) + isolated-char-positions) + (setq start (match-end 2))) + ;; Now collect any remaining ? and *. + (setq start 0) + (while (string-match regexp command start) + (unless (cl-member (match-beginning 0) isolated-char-positions + :test (lambda (pos match) + (<= (car match) pos (cdr match)))) + (push (match-beginning 0) confirm-positions)) + (setq start (match-end 0))) + confirm-positions)) + +(defun dired--mark-positions (positions) + (let ((markers (make-string + (1+ (apply #'max positions)) + ?\s))) + (dolist (pos positions) + (setf (aref markers pos) ?^)) + markers)) + +(defun dired--highlight-no-subst-chars (positions command mark) + (cl-callf substring-no-properties command) + (dolist (pos positions) + (add-face-text-property pos (1+ pos) 'warning nil command)) + (if mark + (concat command "\n" (dired--mark-positions positions)) + command)) + +(defun dired--no-subst-explain (buf char-positions command mark-positions) + (with-current-buffer buf + (erase-buffer) + (insert + (format-message "\ +If your command contains occurrences of `*' surrounded by +whitespace, `dired-do-shell-command' substitutes them for the +entire file list to process. Otherwise, if your command contains +occurrences of `?' surrounded by whitespace or `%s', Dired will +run the command once for each file, substituting `?' for each +file name. + +Your command contains occurrences of `%s' that will not be +substituted, and will be passed through normally to the shell. + +%s +" + "`" + (string (aref command (car char-positions))) + (dired--highlight-no-subst-chars char-positions command mark-positions))))) + +(defun dired--no-subst-ask (char nb-occur details) + (let ((hilit-char (propertize (string char) 'face 'warning))) + (car + (read-multiple-choice + (format-message + (ngettext + "Warning: %d occurrence of `%s' will not be substituted. Proceed?" + "Warning: %d occurrences of `%s' will not be substituted. Proceed?" + nb-occur) + nb-occur hilit-char) + `((?y "yes" "Send shell command without substituting.") + (?n "no" "Abort.") + (?d "toggle details" ,(format-message + "Show/hide occurrences of `%s'" hilit-char)) + ,@(when details + '((?m "toggle markers" "Show/hide `^' markers")))))))) + +(defun dired--no-subst-confirm (char-positions command) + (let ((help-buf (get-buffer-create "*Dired help*")) + (char (aref command (car char-positions))) + (nb-occur (length char-positions)) + (done nil) + (details nil) + (markers nil) + proceed) + (dired--no-subst-explain help-buf char-positions command nil) + (unwind-protect + (save-window-excursion + (while (not done) + (cl-case (dired--no-subst-ask char nb-occur details) + (?y + (setq done t + proceed t)) + (?n + (setq done t + proceed nil)) + (?d + (if details + (progn + (quit-window nil details) + (setq details nil)) + (setq details (display-buffer help-buf)))) + (?m + (setq markers (not markers)) + (dired--no-subst-explain + help-buf char-positions command markers))))) + (kill-buffer help-buf)) + proceed)) ;;;###autoload (defun dired-diff (file &optional switches) @@ -745,28 +854,19 @@ dired-do-shell-command (dired-read-shell-command "! on %s: " current-prefix-arg files) current-prefix-arg files))) - (cl-flet ((need-confirm-p - (cmd str) - (let ((res cmd) - (regexp (regexp-quote str))) - ;; Drop all ? and * surrounded by spaces and `?`. - (while (and (string-match regexp res) - (dired--star-or-qmark-p res str)) - (setq res (replace-match "" t t res 2))) - (string-match regexp res)))) (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) + (confirmations nil) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. - (ok (cond ((not (or on-each no-subst)) - (error "You can not combine `*' and `?' substitution marks")) - ((need-confirm-p command "*") - (y-or-n-p (format-message - "Confirm--do you mean to use `*' as a wildcard? "))) - ((need-confirm-p command "?") - (y-or-n-p (format-message - "Confirm--do you mean to use `?' as a wildcard? "))) - (t)))) + (ok (cond + ((not (or on-each no-subst)) + (error "You can not combine `*' and `?' substitution marks")) + ((setq confirmations (dired--need-confirm-positions command "*")) + (dired--no-subst-confirm confirmations command)) + ((setq confirmations (dired--need-confirm-positions command "?")) + (dired--no-subst-confirm confirmations command)) + (t)))) (cond ((not ok) (message "Command canceled")) (t (if on-each @@ -777,7 +877,7 @@ dired-do-shell-command nil file-list) ;; execute the shell command (dired-run-shell-command - (dired-shell-stuff-it command file-list nil arg)))))))) + (dired-shell-stuff-it command file-list nil arg))))))) ;; Might use {,} for bash or csh: (defvar dired-mark-prefix "" diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ccd3192792..e1d9eefbea 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -28,7 +28,7 @@ dired-test-bug27496 (let* ((foo (make-temp-file "foo")) (files (list foo))) (unwind-protect - (cl-letf (((symbol-function 'y-or-n-p) 'error)) + (cl-letf (((symbol-function 'read-multiple-choice) 'error)) (dired temporary-file-directory) (dired-goto-file foo) ;; `dired-do-shell-command' returns nil on success. @@ -114,6 +114,49 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(defun dired-test--check-highlighting (command positions) + (let ((start 1)) + (dolist (pos positions) + (should-not (text-property-not-all start (1- pos) 'face nil command)) + (should (equal 'warning (get-text-property pos 'face command))) + (setq start (1+ pos))) + (should-not (text-property-not-all + start (length command) 'face nil command)))) + +(ert-deftest dired-test-highlight-metachar () + "Check that non-isolated meta-characters are highlighted." + (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (markers " ^ ^") + (result (dired--highlight-no-subst-chars + (dired--need-confirm-positions command "?") + command + t)) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(15 29))) + ;; Note that `?` is considered isolated, but `*` is not. + (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (markers " ^ ^") + (result (dired--highlight-no-subst-chars + (dired--need-confirm-positions command "*") + command + t)) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(11 25))) + (let* ((command "sed 's/\\?/!/'") + (result (dired--highlight-no-subst-chars + (dired--need-confirm-positions command "?") + command + nil)) + (lines (split-string result "\n"))) + (should (= (length lines) 1)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (dired-test--check-highlighting (nth 0 lines) '(8)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.23.0 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable To try the changes out, it's enough to reload dired-aux.el, mark a few files in Dired, type e.g. ! sed 's/?/!/g' RET =E2=80=A6 and play with the new prompt. Let me know if this UI looks OK, and how the implementation may be improved. Thank you for your patience. Not addressed in this patch series: - letting the user iterate over non-isolated occurrences and selectively substitute them, - allowing '*' to be substituted when surrounded by backquotes, just like '?'. I do find these features valuable (or at least worthy of discussion), however the current bug reports were motivated merely by an inaccurate warning; I'd like to close this first before considering further changes. [1] '?' when not surrounded by whitespace or backquotes, '*' when not surrounded by whitespace. [2] Trying to find the right balance between concision and accurate explanation, considering that some users may not know about the file-substitution feature; also trying to make the highlighting "accessible", i.e. not just relying on colored faces. --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Tue Oct 22 11:11:30 2019 Received: (at 35564) by debbugs.gnu.org; 22 Oct 2019 15:11:31 +0000 Received: from localhost ([127.0.0.1]:60317 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iMvon-0005wh-Rx for submit@debbugs.gnu.org; Tue, 22 Oct 2019 11:11:30 -0400 Received: from mail-wr1-f50.google.com ([209.85.221.50]:35997) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iMvol-0005wR-Co for 35564@debbugs.gnu.org; Tue, 22 Oct 2019 11:11:27 -0400 Received: by mail-wr1-f50.google.com with SMTP id w18so17959794wrt.3 for <35564@debbugs.gnu.org>; Tue, 22 Oct 2019 08:11:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=vNJozqwWJeiYIxGJP5yfNnpywsgzoWZwaNUmUP6r0Z8=; b=ToL5JWeW27omxGmDGK4ai9rbAB+rXSa0V82SELv/EFNrDLIbHFc/hvlI4Vf8dkFE06 N8Yi0YyLCTuh4Z8Lnhm6YoLXUHsu5aURXDZ6ON/H1gbS7qzcl3Mfk2zXGe82sTsF793z wVAM0XyEavQZJrIHkUkzcvb61APWsF2kxBGsrzV/JnlcL+XbSBDs3VRrcao6kQce2rkl hfxoFfeG4y36vxOhhwQaRtLX+0xPCAaGUcO31EYqQ4QW6Cav49vNawKOyRRXZL65mkJG EaznKuaHIkOeLte87f92YuuHuzFhFVaeVSFLbGdAiwgpzSHYez7MJ6Cc/lKVzwgVubT2 NA0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=vNJozqwWJeiYIxGJP5yfNnpywsgzoWZwaNUmUP6r0Z8=; b=XMHTMY2VRuglm69w13+2wqshanlEJH0MfKZp+Zs5Fbtebs9x1tex3VM9u9m8NwhY5n 30ruG53e3F4YOr7muRdxWSyM/iCnWTSaj9AvN/U4yzZxluZPanVFqkoOET7Ex4vQ5t5H dStx1J5Cb5sokgMhx/gGuahenqrN1hehmSnOU7dgUuDA2Y6gc58/RMlpWhY96kDZz9n8 dWnNP/oydR9aQT/YtMmx6NCJgNQOfTcGrKK8/USg43Q5VIUC2fyOPqtCmYIVDQw3QvQ9 YHTBF13w2P0zhlbXHTh4r+BsLYyxqOXh2MFBvJGsYjcjUOoznBpJ7jPL/NqUyK5J1osb DGOg== X-Gm-Message-State: APjAAAXu/3i1Jm0HCzrgs2aCt4VAVYBcAyjxSmH3TEfISbNrsO6kk8Cv GzMtzDAK47UAaanAjFwP4pA= X-Google-Smtp-Source: APXvYqxHHDa3Ybu0FbQ58ljB9pE87bk1yyXbbhsJFcSy6M2bXxvNeOekSO3DBkOcDRDjPp0L5yyicg== X-Received: by 2002:adf:c448:: with SMTP id a8mr4082015wrg.233.1571757069128; Tue, 22 Oct 2019 08:11:09 -0700 (PDT) Received: from little-buster ([92.184.97.84]) by smtp.gmail.com with ESMTPSA id f143sm33768933wme.40.2019.10.22.08.11.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Oct 2019 08:11:07 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: 35564@debbugs.gnu.org Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> Date: Tue, 22 Oct 2019 17:10:54 +0200 In-Reply-To: <87o8yoign9.fsf_-_@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Thu, 10 Oct 2019 20:45:14 +0200") Message-ID: <87v9sgrf29.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , Noam Postavsky , Juri Linkov , Stefan Monnier , Eli Zaretskii , Drew Adams X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Casual and nonchalant bump. I realize that everyone has their plate full right now (Emacs has tabs! Face extension beyond EOL is customizable! What a time to be alive!), so I am not expecting this to get any immediate attention. In case it helps though, here is a comparison when running e.g. sed 's/?/!/': Old prompt: > Confirm--do you mean to use =E2=80=98?=E2=80=99 as a wildcard? (y or n) New prompt based on read-multiple-choice: > Warning: 1 occurrence of =E2=80=98?=E2=80=99 will not be substituted. Pr= oceed? > ([Y]es, [N]o, toggle [D]etails, [?]): Hitting 'd' pops a buffer showing more information[1]. The commands then become: > ([Y]es, [N]o, toggle [D]etails, toggle [M]arkers, [?]) Hitting 'm' shows/hides '^' markers below the occurrences; 'd' quits the details window. Screenshots in GUI session: --=-=-= Content-Type: image/png Content-Disposition: attachment; filename=gui-basic.png Content-Transfer-Encoding: base64 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 AElFTkSuQmCC --=-=-= Content-Type: image/png Content-Disposition: attachment; filename=gui-details.png Content-Transfer-Encoding: base64 iVBORw0KGgoAAAANSUhEUgAABAAAAAJYCAIAAABzcgN0AAAAA3NCSVQICAjb4U/gAAAgAElEQVR4 nOzdd3gURf8A8O9suX6XSy9AeiOEXsUIdlQERKxYQdH3Z+/ltbe3+Or72nvvoiCCDRQQpBpKSAIE Qk3v9fruzvz+2CRcksvl0gDh+3l8fMje7rSd25vZmZ0lycnJgBBCCCGEjgPi+L/17kAp+63+TQnq R4qi9D0Qnuf7HohK6K+AjoQ4ZKKYcm6vD5cKV8jFm/sxPQghhBBCfx2MixgKRGAcD8ABUTeSDvu0 /I+wln+Wbz+6iUQ9JopiXw6XJInjOEppvyTGdweA8QJodNTWyHEcIe3qHCMcJYTIEiGkw0cqMfls 0lwKhDBoO5ZA2z+8QgIAYEz9BwMgwNTDsQOAEEIIoZMUo8AJQEQgPHA8AzjSfCItrSd1PwJw5G/W P+1CNKD6q/ned1znTZQXp9xw15zHnpd5TYeEMsaU0WdIVz3sIkKXeWCUtYSs/sczwjPgADjWurHt T0Z4AB6AI+oWRrAGI4QQQujkxRhjHAWOgshAACIyIgAnMk7DiMg4DXAiIwIQkYFAQaQgMCYAY92H jFCrjiMAjBdm3fnQ3+ZeZlPg8Lzb1r/zIiGU41r6CSw2LXjuXXbRUA08+/RZneLxMRuJUQBgwAAY IwQYU3uujBAgpKV+qpsZa9mTtA0FMOwAIIQQQuhEwUVe8OiTF8dpfMyZUDG56qcXHv628Mg9WdYy c4IjjCMECABhAG2TKRhT/80YURtYrOWo3sfYxwPR8eLLL78cPXo0AGzbtm3u3Ll+9mzXAWAa3ey7 //7ItZc5Febx0Ouvn1dWUnLohy9EUeQ4joVExvztSWq2ODwKNyKr/qrHrF88p5ddHfsAjKo1hzEg rY1/temvcckmG9UBD0AdTLFbeFnDtYxntewJDDsACCGEEDpBcKEJ1s1PX/lynuT7cyH15vevD1c8 hbyuZQujpOU+KkREw2On6DUdHwM4crNfqi98+SfTPo3Rq/nU8xj7eiA6XowePXrixImEkE2bNvnf s10HIPOS6+dfOtsmMxdlbspEnrvytrv/V7jbvTeHN1oGzX84KHpwrYcxBowQT8YptonTtX9806kD wAAotDX9GWEEBBdLdOgSouLNaSEczzNKFZfUVFq1r6qo2EqpyAFhLYMAOIaFEEIIoROH2+HhgoKC fH4mU2Z3tm/5MNZyD5XRYCvb/Pabr+xTwFfzn/ARCx47NbS2cF/UyPbNpx7G2A8HnnREUZSkLnpK R13bjX8A2Ly55UnagoIC6HoooF0HYNcP3/yYddpZ40bKjNllZleoQa+/4O//WvT3W6JnXD1kxLg6 icmMygwUhYq5a4x/LPbxHDCjQBkABcLUESyDXRlniIscH08AGGVMoWGh+pjo8IpIc1BRePi+Pbli rcfAt9R4HAFACCGE0MlLbQgxBhQYc/DhoROnsfbNLcIYAJOa6+3u1hnUcCybT0yIHDPnhvmzJiZa SePelR+++NqvxYrPje0OI+ak8+fddOnU4YMtnL1s9x/fffDe93mNPvsYnDnzlNiDa3baO8xd5y2j r3vqselFT0z/X54OAGTFev4LC/8+QV1vh9Z/d/tlr+ySvaLUpl/ywH1XTIwRGnf/+Nbz7/5RyQD4 0Mk33r/grFSrKFXvWPbGi1/kNPsvTUEQJk6cuG7dup4X1YBQb/w3NjZ22G61WrsaCmhXjrSx5t1H 7pL//eaooSkuhdlkZlcgIir6zOfe5k3WJpl5KPNQkChT8jYEffEPHSg833kdIdpyI58BI0QjKWMN 8VFDE4AxpjCgLCrCYAnSZowIv/CS1Jef3DAkNlU+sCtXqKM813o4QgghhNBJSb0ZyighMgAHQIEp RH1ikqgPCLQsnwiMAvDqDsd2AoWDHzTUvO3l+Y9vq9GNuuml/945bcd9Pxz0tbHqyPMDfNSsp1+4 pO6D5258OLeSBqedfsNDT/3L/MidH+/2dHzGgJKw066Za315ZbsOADHGz3rw8XOdh6u8mo5cUKh5 75uXz//wIANgjFKT2XIkHGHYNQ/PdL5xzZm/NaVc+98X7zpn79+Xl2gm33xPRs6dc27d5QqZ+vB7 D8zNverNXNblcw5q67+rcZIeIYSIomg2m41Go0ajIYR4PB6bzWaz2SRJ6tGSQY2NjUPvKyac1ypR lOx+ocv92zXfCSFKXdXHj91te/rlhPg4JwW7TG0yNVtDGiTqVJiLMresOHZv1X/8lE7xCKLoewSA tczkIQCxDnPUiASgLDraODlrsMWsMZo0BqPocclF+xo8dhlkGh+TUnFwU0UEbTkcIYQQQujkxBgA Iy0ro6jNffVPoi76T4AxIBww0tLWYgQYO6YdAK39z3dechkMBosJdq7ZUnXeoBBFLvO1sYrXqIfI 4pgr50aufPKOxblUFDW0af+yfz0V88mbV05e+MTvHiFu2t/uuurs9HCucffnf39877SnFoxJIi9+ c74z+82b/rNB1gKAx223Ff3yxC3b0v/1SWZrSiizhFjq9jbxRqO2LXmKccpjH9xQ99TVr7omnOpZ 8eS6WoNZX7h44da5l00I+rFYNplZ6cFyyRxktB8+VM0n8rIEvLZjJgGgtfVvtVr7Xmg8z1ut1piY GKPRqDan1ZNICHG5XOXl5TU1NbIsdxfMEd6t/85/dtDx/j0hRKoo+vrR28975vWI6Bi7zGwybZZZ s8zsCnNISmN+NnnnEb3iFn22/kFtwbcMSAlulhQdB5QxhVlMmvSM0MP7Gz5/K6emwsZkBor6HyUK ixcjK5UyxnPYAUAIIYTQSUy9H8pAXVadUsIotL4uqfW1Si2jBK1zLo7xFCBBEEwmEwAAcKGZw6yF PxQD53Nj2yEsJiNT2PpmnkcU9QDAcZxRW75+U/3sEUlkg3D9U9eHfXPvrJsLWViUvqGseucLYyc9 YH/wmnf2UY1Go9EAAGg0ULJhFSdEDvVqjTKiN1rG/N9HP9xmgMbCtV+/8ebP+z2ys6Jg+/bGKg+f NiS0dGUlEQFAoGUHqwbHRStsx5rPV82+7+kbdEsrUy87v+ndR7ZRjvh65e706dN9Zv/yyy/Pz88H gMzMzK+//jrAQjMYDHFxcRqNpqqqqqmpye12M8Y0Gk1QUFBoaGhcXJwkSXV1dQPUtfPxIjBCCKsq WfHcAxP+/l9jcKhdpjaZ2WRqk2l9Zbnn7UcMHruo1fpu/YO6fm3L47wGOzGmh4JMQWG7c6q+8dCz pieOmhC1aWVRc60LFAoKYwoDhVqNYWLTIbdViw8BI4QQQujEwcdOu+X+iCrfzRvGhY1Mdn/UblPb jdS2LQp0aHS1W/qz0yrqPY2x7we2ohFnP3C1fuEDv9k4HfG7UTGYjbamZq+ZNhzHNTY06wdZ5Pgx Z8Cvjy0uBIOB2RocglHDCQBAOM5kMnhHp9PpZNpurg6R1j83axZnq3NwYaPmPv380zeWz3ttq6vg s8dzNBqtfqQWPB63Gh3xuNw6nZ5oREfuokUHX7rp5rtEQ82SJ/+sIKLGby472rFjx8iRIwFA7QYE yO12l5aWut1unU43bty41NRUnucPHTq0ZcuWvXv3Go1Gh8MxcAM7vt8EDABU1DZR4vZQh0LtMmuW abNEXeZQeeRUtuVnxljXHQAKkoNRCRRJ5zHxHMdkprb1K0qa1q04OC5r8IQpQ7atLVn57V6326OO A+g5PW9rYhpCdMEDlFWEEEIIoaOLVuzOd14yfERUy9+cOSYh2F1cVOtRP1bs9VtWlyoAbbecGSNU BqAEZMLHnjvrlAh75xaXOmMkYvjgps8UD5FdXvdPex5jXw9sTVPIKXc+e3nTK7cuLBI4kfjZCADQ 3GQ3RVjaB2Wxmp3NNhpstdTnNYkaAGh5FVXAwxsajUgViTMGWUDK//rz36+4a2QM3X5IMBgMAOB2 ukCr1QC4AYBodRqX08lo2LRn/3Pmjgdm31fApV300LMv3/PGra9ucXT5NoTO2tbD9PF2rK55PJ7K ysr09PR58+YNGTLE7XYDwIQJE84999wvvvhi/fr1A/raYB8dAMYYSxoRf+c/FIOl3qM4FOZQmE2m zRK1Md518Z2gyNz2X9WXA/gI0mtAijLKZAoKs1i0F16aljQ0RPIoeZvL136/79DuOndzS+ufUwgv c8AoMJwChBBCCKETBi1d+vi8JRQAYMi0268aGxJnijM0Hty1u6pw2Vvf5NsYEEJ0Op1Xi+rITd+K /cXO82OHh7U0jThDULxFKqlwtLbIXQ27SspYh6N6EWMfDwQAgKBxC55dYPrkzmf+aBB0On8b1eQW 5+bLD5wyQped15JySuKzJgXv/HSX0nx6szUshEB1oIXcTlvrlBdFgbgdNqmtuespOlgZHTeYh/0A VBgUH1W2p4QJY08duXvhE/slk1Gz/8e3Fp3/5qlJ/9uSJwYeY2ZmZn5+vqIoI0eOzM3N7VFqGxsb s7OzV6xYsX//fkVRkpOTBw8eXFlZOdAPdXR6EzBjNGV02E2Pe3Rmu5u6KXPK1KlQuwJ2hbkUxrT6 5svv49x2y+5Nokj8PQTMqJu5FJfEEW7WlekJqSGNdc4P/vVnY5VDnfYDChCFcTInKJzH6ZIFCgwf AkYIIYTQiUOv16v/cNTlLPmigCOffwQAAMxVyzRao9DpVuyRhhCryNu+YPNKAGDWuFvPjw2OTo7V OQ7uK60q2vbeOoeNAeE1hiGj+XZH9TzGPh/ITKPmPXf74GUPP7veZg4OBsZkyeXR+9gotS4EKirb P/u84p37Hy56/p1fC+plS9KkufdcQr+9b62NCms3aP9++bSfX/it0m0eHCYfKm5qarCHpidauDKJ MtpxQpQXtzVtSkzj7n1VTSx49GVXn1q1+p5KjhqGXnz72fYvXll2cO0a9tTFWT++tNE9aOacicV/ fFbPOUvLbENPOyUye2MDZ0yceuqQ8k0lMoCPDsCPP/7o8yHgtnn/6tL7PVJRUbFkyZLo6OgzzzxT r9f//vvv69atUxTlqHYAGGNS0kjdjU86DUE2D5MY9SjMsX+nJ2et47z5MteyMxN1jXMfgU+fthRm i4LQsQ/QMgJAgVG7xtVYXm2NCD+wszY+JZgxFj3IpDhlW72LyYwoRJB5XuF4mStvLvdY2p5oQQgh hBA6oWiVxqrKBu8tPM/7aMl6tfyMQ1re7tRclL30p2KOrP9U3cVtI9ETLOYIn0f1OMa+HsjpT71q 7rBYcdjnyx8AAABa+90dM98Z3Hnjha/sbBkHEARS9PWDd7puvu3et28ebOHs5TvXfvPA7V/tA73o 2f7SAx/e/8B/v7o7hGvI/eD+O75tLv/x49+n3v314luzX7nxyVX2LufoU4ic/H+PPZgQomX20q3f P/fgJ0WcXuZCMyaMr1nq1vAHP3jy80cff+e7R/X2fb+99uTXZZwG8j984rt7737927sFQu0HVv/v maWVPHQRgyzLmzdv7q+FgACAMaYu9ZOQkBAWFvbHH38cnfeLkeTk5LY/nHHDPNc9LljDGDCFgUxB bqzV/O8WXW1Z8/QFTWfMBa85P5ytwfrR4+bDeaLYrpNkGD+f2mtA8TDZDUxJdMSMGXoaUBYz2Dwq KyZhaKjZqpMlqkjUYNHUFtu+vm+r3Kz83Li0ItQBAHxosiP7g6OQc4QQQgih44047GI+djIAB0Da bnXLjgameLx3EwzBhD/SAFMOr5V2Lj6qCfXS+RVUPM8ritJ5Y+u6QC3cbrfH46GUqivia7VadQKP JEkul0vdrtVqtVpt2556vb5lGSAAAJBl2W63t4XsfaAgCDqdjuM4SZKcTqcaTtsOHMfp9XpBELyT wXGcRqPRan2vAdpGEIRJkyb16EVgiqKIotjVtH5CSFpamsFgyMnJ6WofPyEUFBSkp6dnPFDUYfuu 52PVj3xk4Ui4BnPtRXcpOit4FGBAAZjDZn7/cX1tqUaj0az+nJqCbePPA67l+QZqsDgzs4wHd3QM 8sgIAANGi8SyqMP7YqITSvc3lO6t02iEuJTgQQnW4DCDo9pTsLKSNcHuhpyq4GZgpPVwhBBCCKGT kq+GkGDo7n7zMW0+9fqtWGqjvPN2URQ73F/uak9BELxj73xgh40+d+gq8K6o4wCB798txlgvpg91 DISSDi8C87PzkQ4AZ2+yLn21+opHFHMwAIDkNi16yXggR6P2xqgS9uObiiHIOTwLAIBS7bollmVv +nje+cgzAAwYk3llq2MrlNCosHhR4IKD9DV7bcUb6wWZ42WOl7mChu3Z5nzKkZbRK+wAIIQQQuik 1buGEDafjq6jM1EncFartfN7f/3MUzrSASCEGA/sgM+fqbrqMWoM0q/+2rx1uVajaXuYWpA94Ytf rLCGeQalajf9YP3+VR3na8GjtvVrWyf0u7X0Tyl7yMHiJFM6NESIVBAVHiRWZS/N9eSUWGup4DV3 DWswQgghhE5avXv6E1+jdBLbtm3bpk2bfH60detWn9vbPQRMCDEezov49Inm4VMty9/XdlroU3TZ Ir54rmnUmaZfP9HwhOf5rlYBYowxOPJEryTAAVNpkVSmb+KNzAiMNRGbW68oJnXaT/vDEUIIIYRO Ur1rymMH4OQ1d+7cnh7ScUUnQoixeLe+uAAEgeO4Du17Qoi2oSJs9ecg8IT4WgMUWvugbbOAvMgC azbTZmjouHPnwxFCCCGETkI4BQgNPB9LuhJCeADo4mVmXbb7W3lKtmoGjQatuXcJ8pT4HqpACCGE EDrx4RSgE9Rx9dhAl+906DW5Zq9cs7ffg0UIIYQQOgkwZf9vxzoNqJ/xPN9hXv2xRaKjo491GhBC CCGEEEJHCdm2bduxTgNCCCGEEELoKDmOBiMQQgghhBBCAw07AAghhBBCCJ1EsAOAEEIIIYTQSQQ7 AAghhBBCCJ1EsAOAEEIIIYTQSQQ7AAghhBBCCJ1EetgBcOd/8ezbG+oB5NyPH35tXeNRfu2c8893 Hnh3q/tIMo6t4yQZAWC1279+4bGHHnz05ZXlimP/L288/dADDz377Z7j6JV0fhybynaik3M/fviN Dc1YqgPtOLtqdaX7b9nxkRG8GiCEUH/w+yZgWvLT8y/8UkbVvzjDxAXPzTx1ltZkARiIy6+P6K4a xvvaUxvXkgyAhr3ba6NHJZlJ7+Nl9kPrli1bm3e4xgH6sPgRUy6ckRVv7DLAIzF6JeNooyU/Pf/C 8nJGCMfrLJGJY86dPX1UeFdnUzm45ofC+GufvDdRUEjjhtf/4M996N8TTQrr/xdB+47/0Pf/+N/K au9KQ8LOuuuRWQk+T+/R0MOT3mv9UD87oyU/Pf/CCvvEvz1+ZbrYso01//nOM5/vSbzymZsnDUA+ uknML2WUcLzGFBY74pxLLpoQrTmKCeih2s2fvPNdThWEZlww/4Yp0UdvDLS7y8WAVBWQK7cs+eaX rQdr3YI5KjHrkuvPTdT2Mcj+ve7Rkp+ef88+57FLU1ouBu6t7z6WPfyJo1yNEULoJNNtC9Cadesj l6TwAEAIBwTIcDMAgDxA6ekYXQetG8xxajJYzfZfVnkuHZVk7nWMSvmqd99abznvirvmx1tJc3HO L1+/+7bzljvPHeSzcdouxtZkHBvWrNseuzSFUxwV279774tFkUk3T+qi8aA01DeHDx+sIzwISkNN Q1BcXBAhRDhaP7B8/KxHX5rBGD287N9fsCsfnBnPEcKRY/f73sOT3mv9UD+7wIWF63ZvKXCnD29p zjXmbq0JijhGDW/rabc/dmkyOGsKVnzy6Rdr4u45J/K4bbyFTrz6mpqyDzyXzT9arf+OVy2fBqaq sMrfP/u2OP2GBxfEa1115eWuUL+tf9L5ktv+Y9Wxve4hhBDqB93fAiYcx3GtP5Ry7sePrU166NYs 45EdPGUbF321PLdK0keNnD734rERfbqt3C46AABmK1z+xcK1+21CSOpp6TI5kowHr7WseG/FwSr6 xlMbtUMvefDyTLGLQP3w7Fm1umHM1f93eqoWACA0cfLlV1T/+/2V+VOuHbb3k6e3RZ3J5azaVSMZ 4idfctWMIYe/8YrxvqFbn1qb9NCtWUHgLtm4+JsVuZVuzjxk/PTLLhwVJsi5nzybM+hsfsfKnRV2 PmLkhddeMTGClm5Y+NWKXdVuRROUeOY1N5ze5xYn4Q3Ro8elfP99fTMDk/PPt5/Mm/DsDWM0ACDv +OjRDal3Tan+dtkeT/P+fz3529BJ45q2/1lXDW889WfCeXfMH+PodO7k3E//sSvjEtPGhWuKYi59 8vpBOd/0R4LVBj8HAIQj6hlmPgrN98ZWUj+VXs9OekaQz0reoaAWjG3c+OXC1Xsrm1wkNHP6NXMn Rztzv2lXP1Or+/GbYsgYHpazrcA5fKQeAKA2Z3vzsJHRm0vUT5XyDR0S0ynB83QtITFH4dI3vq6b +n/XjQ/tS4uY8PrwjAnDQv6srqMQqfi4LDD7/t8+/2r1fpsQkjp1om7T/tT7bhir7Vy2jVs++O+q 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 CQAAAABJRU5ErkJggg== --=-=-= Content-Type: image/png Content-Disposition: attachment; filename=gui-markers.png Content-Transfer-Encoding: base64 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 gg== --=-=-= Content-Type: text/plain Screenshots in TTY: --=-=-= Content-Type: image/png Content-Disposition: attachment; filename=tty-basic.png Content-Transfer-Encoding: base64 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 MMHClI8AAAAASUVORK5CYII= --=-=-= Content-Type: image/png Content-Disposition: attachment; filename=tty-details.png Content-Transfer-Encoding: base64 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 --=-=-= Content-Type: image/png Content-Disposition: attachment; filename=tty-markers.png Content-Transfer-Encoding: base64 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 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable The patch(es) can be found in my previous message[2] (along with some context and rationale). Let me know if there is anything I can do to help with the review. Thank you for your time. [1] Contents of the details buffer: > If your command contains occurrences of =E2=80=98*=E2=80=99 surrounde= d by > whitespace, =E2=80=98dired-do-shell-command=E2=80=99 substitutes them= for the > entire file list to process. Otherwise, if your command contains > occurrences of =E2=80=98?=E2=80=99 surrounded by whitespace or =E2=80= =98`=E2=80=99, Dired will > run the command once for each file, substituting =E2=80=98?=E2=80=99 = for each > file name. > > Your command contains occurrences of =E2=80=98?=E2=80=99 that will no= t be > substituted, and will be passed through normally to the shell. > > sed 's/?/!/' '?' is highlighted with the warning face. [2] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D35564#157 --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Tue Oct 22 13:12:06 2019 Received: (at 35564) by debbugs.gnu.org; 22 Oct 2019 17:12:06 +0000 Received: from localhost ([127.0.0.1]:60417 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iMxhW-0000Ti-CY for submit@debbugs.gnu.org; Tue, 22 Oct 2019 13:12:06 -0400 Received: from mout.web.de ([212.227.17.11]:38895) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iMxhS-0000TC-Tt for 35564@debbugs.gnu.org; Tue, 22 Oct 2019 13:12:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1571764314; bh=9AtwbYpLhbwyt7PM9bnRR9t9qp8G++hSM8RUEDDcI8c=; h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To; b=ElOMgvwPgoJ+x8gEaswELJ6cKEHv6+k38r5aGzJYnH75yDCPtSBl53nZXL5hFAma3 HbDaVU8qabKVW4ItGnalniF+g9DNtes+XrhtKELRq612Kanl7bWtZyVP6nLnGUL0pP YyUaeKFbUABRKQMhlQyfdigFuKFXGl12Kyc3Fc2A= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from drachen.dragon ([94.218.222.9]) by smtp.web.de (mrweb102 [213.165.67.124]) with ESMTPSA (Nemesis) id 0LpO93-1hqtva25hd-00fEko; Tue, 22 Oct 2019 18:58:19 +0200 From: Michael Heerdegen To: =?utf-8?Q?K=C3=A9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87v9sgrf29.fsf@gmail.com> Date: Tue, 22 Oct 2019 18:58:21 +0200 In-Reply-To: <87v9sgrf29.fsf@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Tue, 22 Oct 2019 17:10:54 +0200") Message-ID: <87zhhsd8eq.fsf@web.de> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:5MPrpsK/fZBdP1i/sPqXUZiV5DQD+zSPPkaY3XMBtvG7XK03+UO 47G4Ha0RSCQl3fyr5Sz9PwdSQTLdRtsELWhIanX4KNHEx0LIhGCPpzGbxKADxHSIs3/RZCL SpmTpmOHGAOcqTsaWP2gl9EX2SpoLxlK7ottbjuEJ5TjxyhkYB32RFilQf6vGt98ZLGh88L jvtG35Dymu2xwKQqdqNGg== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:qv78BLdEsa8=:dFeJCpWy/NGgZEf8kwQ/kf E0kySXF6/TXpJmXS1s5zfaF8H3b1bfqt8oC/QlhDu8ESevHkCWdvHW+FtHBNBSSXX+oVSTzpF HIRR2jDL2p3Kji+jjpjJttJ/Pts09KCmpfGX2fBfPea5PMV8ghJpXu63peQzDKelV3JkGA+ue t4oVXXuVWQlWPspH5fH5/vKy7FKWXhzXENZV1j760qSkkbdzaa206Q2O+rO+/AL6+O/ejiAuq bOYvBmSRDVorhHJXye6GEIm6OQN8Dk7+/uN3jJHbOlgNDwnjsc3uEa0kWSqudk42ftq1telkh rRNno15L2xomEpuKFb0Afnc4ltRFTfivbXjcN6ss2RYEN6gz8bVJeU7ZrqXY7f2jlsOyckFH5 wsJILhkcfg+/ll6pj4sbLLCbBpzH1a/fZ5rzhLGFuaeyRkkKdl7EzoR37/vYqEdz5d1LI5Yy0 0VRCiCKUMRIEJDjG6/dIRTwyd2SKhS/5/bDClwkyBGiTKxxKVLAug94ftjtjvrUNW59hGQqO/ mF5X1nyaaz4QHJ13X2dvzH1eOgAan6Ff1Cwf6dshuDMfEWT6Lc2IBLymgLSbv/p6jbOqtjJ8D VUc2EX0o4R5Yn1V7vjbUAhL9OWw4/itUZcUFtFxwU3NkSOVFqe6b962eMEuVXnxobYyC3IGdB 09/hvZxqDgh1zkS0B1l+2WqU8SVA4TAw7IRV03xeKmlLd7pXLQvZa0ZutK6k8oVRn1rgHPjQP D4whmcnLKLQY5nVVu/QhOWcsqkbnApYZmBHy2c3xiD4eBMJERDLoFAD4XSmnkmTpERp0o96ZC CMYZxPvwxYUDKqdFree6DZnIrTAsp0HQ0JM/4s46TUM7knB6/dMUmEjQHWiQ/npCoxr2PMz28 aEgBkKxwUT1HLbhnYaGPqr2J8eJXz8Cm0GNfhhux9UNImU+6aI+XicY6LIHFvt4qNrIejoXQ4 9wQOM/0sPwb7MwdurDH9Eii+mI7zvBcAVcUxsqYyqCyQPsUfsNmVAFMGkuPesudHbOLLFjN2p PcMH/GMV398zgcgGJjFaY+fQs72Nvk+ELpHDYWuQI+V98a02n97j7wu6nlCuBLk6ia6baQKfZ tyjQcnlWFIDLr2AGxgg2ODYtjq3hEK099sCiweL++rcx0r8PDXV5tqF/uI16YQ6Mh/JXn0a++ 2TNlGEqTryTZMkZqwdHMw4rXL/3LpAV19Bd31xG2G4UA9HG4555qCG8Q06yxQ1jZ7kzuWfJsj nlFS+/wE1H5y2ipMMTMO7tG2M9i97ChDOvqGRQoPWURi68+9eKGsYeafCLG8= X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Noam Postavsky , Juri Linkov , Stefan Monnier , Eli Zaretskii , Drew Adams X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) K=C3=A9vin Le Gouguec writes: > Casual and nonchalant bump. > > I realize that everyone has their plate full right now (Emacs has tabs! > Face extension beyond EOL is customizable! What a time to be alive!) Yeah, indeed. Looking at your patch is at my list - will have a look soon. Thanks for your summary, that is very kind and useful. Without having had a look yet - your last version addresses everything brought up so far and can be considered final, right? Thanks, Michael. From debbugs-submit-bounces@debbugs.gnu.org Tue Oct 22 16:45:27 2019 Received: (at 35564) by debbugs.gnu.org; 22 Oct 2019 20:45:27 +0000 Received: from localhost ([127.0.0.1]:60531 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iN11z-0005cW-GC for submit@debbugs.gnu.org; Tue, 22 Oct 2019 16:45:27 -0400 Received: from pdx1-sub0-mail-fallback-a1.dreamhost.com ([64.90.62.138]:47448) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iN11x-0005cI-D3 for 35564@debbugs.gnu.org; Tue, 22 Oct 2019 16:45:26 -0400 Received: from pdx1-sub0-mail-a90.g.dreamhost.com (unknown [10.35.43.115]) by pdx1-sub0-mail-fallback-a1.dreamhost.com (Postfix) with ESMTP id 265AE275670; Tue, 22 Oct 2019 13:45:19 -0700 (PDT) Received: from mail.jurta.org (m91-129-98-153.cust.tele2.ee [91.129.98.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a90.g.dreamhost.com (Postfix) with ESMTPSA id 6CA0882420; Tue, 22 Oct 2019 13:45:12 -0700 (PDT) From: Juri Linkov To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters Organization: LINKOV.NET References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87v9sgrf29.fsf@gmail.com> Date: Tue, 22 Oct 2019 23:43:58 +0300 In-Reply-To: <87v9sgrf29.fsf@gmail.com> (=?iso-8859-1?Q?=22K=E9vin?= Le Gouguec"'s message of "Tue, 22 Oct 2019 17:10:54 +0200") Message-ID: <87d0eoseax.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier , Eli Zaretskii , Drew Adams X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > I realize that everyone has their plate full right now (Emacs has tabs! > Face extension beyond EOL is customizable! What a time to be alive!), > so I am not expecting this to get any immediate attention. Sorry for leaving your new mail unanswered for so long (although I marked your mail with the "read-later" tag :) > New prompt based on read-multiple-choice: > >> Warning: 1 occurrence of =E2=80=98?=E2=80=99 will not be substituted. = Proceed? >> ([Y]es, [N]o, toggle [D]etails, [?]): > > Hitting 'd' pops a buffer showing more information[1]. The commands > then become: > >> ([Y]es, [N]o, toggle [D]etails, toggle [M]arkers, [?]) > > Hitting 'm' shows/hides '^' markers below the occurrences; 'd' quits th= e > details window. Finally we have the best solution where the prompt is concise and fits into one line, still allowing to show more information on demand, thanks for that. Some minor details that I still don't understand: 1. Why there is the verbose option =E2=80=9Ctoggle [D]etails=E2=80=9D while just =E2=80=9C[?]=E2=80=9D should be enough. For example, like in query-replace typing =E2=80=98?=E2=80=99 displays the Help window, just typing =E2=80=98?=E2=80=99 here could display the Dired Help. 2. Would it be possible to customize the prompt to accept short answers =E2=80=9Cy, n=E2=80=9D instead of long answers =E2=80=9C= Yes, No=E2=80=9D? When =E2=80=98read-answer-short=E2=80=99 is =E2=80=98auto=E2=80=99 by = default, the behaviour of =E2=80=98read-answer=E2=80=99 depends on whether `yes-or-no-p' is set to `y-or-n-p'. In this case =E2=80=98read-answer=E2=80=99 accepts short single-key answers. From debbugs-submit-bounces@debbugs.gnu.org Tue Oct 22 17:11:21 2019 Received: (at 35564) by debbugs.gnu.org; 22 Oct 2019 21:11:21 +0000 Received: from localhost ([127.0.0.1]:60547 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iN1R2-0006FT-RV for submit@debbugs.gnu.org; Tue, 22 Oct 2019 17:11:21 -0400 Received: from mail-wm1-f49.google.com ([209.85.128.49]:53149) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iN1R0-0006FE-Uw for 35564@debbugs.gnu.org; Tue, 22 Oct 2019 17:11:19 -0400 Received: by mail-wm1-f49.google.com with SMTP id r19so18887321wmh.2 for <35564@debbugs.gnu.org>; Tue, 22 Oct 2019 14:11:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=rSxuxi9syfs7e3KeKuQj0CF2vu68NrRIBV0QmV/qYSw=; b=QVHHiL87QtiHzWXwlXI/vDYzlPSAKzBwnmMTzA+WPfqI1iWe7bw9wcuMYDb8VPMfjM eIXUicetfq2JFmTeMecTTqdHjJ7r5IX78bKUoWhLAEFmalVhrn3vbnA/5TCE/SA41Nb9 shMNIdwiVvE20OOPVzpGuTnAPT+OtDtE67dDeePHmJT4Ngp0zWJq2KffgMdPkm9SPU4m W/Q2lv5po6aNjG1xShCJC2zXPwlxgWyVKcuAzJ1Srm23oMqKORWgCmXNFXzQW9uV/LXq NjV/kYsjfc3ocwbwuKdiL/8xqs1tlYvtM6uz6DOQGn3tFEqv23YpRriXKFi4rFx2mU+Y 0Ulw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=rSxuxi9syfs7e3KeKuQj0CF2vu68NrRIBV0QmV/qYSw=; b=K/hDVxoL+GTn7S30Lx9TZWjlXu1zdi9nNq3JwgWMB3pUZzt+nEhVBldJ9jnZqSjqS/ Bq1Yrz6DB24MJ3FqsKbMrXlLAlS5obDIX/HkdeiIfisYzL6L4ozYLlexrKyg3S7xWyVX 2wF7Xqgx6wdhImRExMId8VOCoZ8LRu5DjuWXwZW1xGWJvDhVcTsQ004YLNLdfj67z51t TdCjgfxnuTy2dYnzDowfRXG0O5SxvZ1b0huS+OEWCfLQy+JGD0qriLUy4P7ayZnOz0jo PslQe3Cb4uXet9y6T9YxPwfgX7AikuLoHdAbRO/OhMgfvIQpxVupt6K1XF061IHkDuYC QZyg== X-Gm-Message-State: APjAAAWWd+9YsFGnkFnUvV6omsNrBKe4BlBapIurGgAgwG1RDZ4FMtkk QHHg4kbfAEzqWGgzmP1IczI= X-Google-Smtp-Source: APXvYqzq3OpDRA/DsY/MQzS4sNJrecPtQaGIfakshOffzvTawJMJLL84lXiu0v6jhHkeOGDymqZ2zQ== X-Received: by 2002:a1c:a556:: with SMTP id o83mr5030464wme.0.1571778673157; Tue, 22 Oct 2019 14:11:13 -0700 (PDT) Received: from little-buster ([92.184.101.100]) by smtp.gmail.com with ESMTPSA id q25sm3123141wra.3.2019.10.22.14.11.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Oct 2019 14:11:12 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Juri Linkov Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87v9sgrf29.fsf@gmail.com> <87d0eoseax.fsf@mail.linkov.net> Date: Tue, 22 Oct 2019 23:11:08 +0200 In-Reply-To: <87d0eoseax.fsf@mail.linkov.net> (Juri Linkov's message of "Tue, 22 Oct 2019 23:43:58 +0300") Message-ID: <87mudstrir.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier , Eli Zaretskii , Drew Adams X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Juri Linkov writes: > 1. Why there is the verbose option =E2=80=9Ctoggle [D]etails=E2=80=9D > while just =E2=80=9C[?]=E2=80=9D should be enough. For example, like > in query-replace typing =E2=80=98?=E2=80=99 displays the Help window, > just typing =E2=80=98?=E2=80=99 here could display the Dired Help. '?' is an automatic option added by read-multiple-choice. It pops-up an autogenerated buffer repeating the prompt and showing longer descriptions for each option. I would have liked '?' to show what I ended up putting in the "details" buffer; ideally read-multiple-choice would have an optional HELP-MESSAGE argument that could be squeezed between the prompt and the key description when showing the help buffer. Since that's not how things work, I went for the additional option ('d'). > 2. Would it be possible to customize the prompt to accept > short answers =E2=80=9Cy, n=E2=80=9D instead of long answers =E2=80=9C= Yes, No=E2=80=9D? > When =E2=80=98read-answer-short=E2=80=99 is =E2=80=98auto=E2=80=99 by = default, > the behaviour of =E2=80=98read-answer=E2=80=99 depends on whether > `yes-or-no-p' is set to `y-or-n-p'. In this case > =E2=80=98read-answer=E2=80=99 accepts short single-key answers. I didn't know about read-answer, that was an interesting discovery. read-multiple-choice only accepts single-key answers, you cannot answer with long options if I'm not mistaken. You cannot choose what the prompt looks like either; you simply provide a list of (KEY NAME [DESCRIPTION]) tuples; NAMEs will be shown in the prompt, DESCRIPTIONs will be shown in the auto-generated help buffer. (Let me know if that does not answer your question; I might have misunderstood.) From debbugs-submit-bounces@debbugs.gnu.org Tue Oct 22 17:32:29 2019 Received: (at 35564) by debbugs.gnu.org; 22 Oct 2019 21:32:29 +0000 Received: from localhost ([127.0.0.1]:60564 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iN1lU-0006ld-Mn for submit@debbugs.gnu.org; Tue, 22 Oct 2019 17:32:28 -0400 Received: from mail-wm1-f49.google.com ([209.85.128.49]:40557) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iN1lS-0006lN-Hq for 35564@debbugs.gnu.org; Tue, 22 Oct 2019 17:32:27 -0400 Received: by mail-wm1-f49.google.com with SMTP id b24so17518657wmj.5 for <35564@debbugs.gnu.org>; Tue, 22 Oct 2019 14:32:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=gytPf1fRIq8RqSRx10DcoGqyOULRmYhDmbZ/CqSHCr4=; b=ZyJLOY8VIciWZcOzezbZxtTdHlXCi+vwYfnvMIBuqChw3T+auoQITeeqvd6oNL78cd a4zz15vzpPaV2yseL3hiJ+/YUKB5VFBNPAVzrZy4td6gbODuDH3uQoF7uMgx5ljkd3uo 5RlNgjE93edvCu/Vokp0CO9aw6twjRTRKq3vfmtRNoDrct9c47JydDeiK4cLBEQJfEnR HizwQx6TilIvsp0E4d9W8uwSaB68iQ3lBLINqSvSf47cQ2mjXKihuBr40KgS9WcVQuQK 5ALdBnLL81p4WxnfnaCaBIZSIE07GWaQK2+NiiASFr6xW91xnvCxq8rcyVOEkItT76Tz OVmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=gytPf1fRIq8RqSRx10DcoGqyOULRmYhDmbZ/CqSHCr4=; b=i3YNxD5LXXlpER0VIC8Q1ilWclf7IzVjgZLNzskBJxhP2eAdnq8A/YOEjxodtVO0gZ 4gFzrCem0LnqcGDLfFoMMN5PdqcAkf0o/XO7g3EAQjr4hUcnzQmy232y7KHjOnf6/k/2 BMkCcV8E0P//qV+CNcPr4YVA1gwI5ccRu4B5ltX6/E3Hvbuw2L/vtPN6ySckmMYKBINR cOBfzbndSU2db++xTB3uZv4k9X0Tzp/pPB/VJEYDMDVOSqO0VS0SAQ/iv8SmOhtyPDCU LTQIRdeGERPundIdvvDIk+x7L1yJKWc+JCk7a7PePAtvwVIlFZBrFFM8I5mbW6/AUweo B3Jg== X-Gm-Message-State: APjAAAXp/oHG6HSTmr2IhJ7B4fyCz5DbcHV8wCgWTZ1XaJPIEDq9yOCc Zj/kG6TlgbUL25WdJVGZbro= X-Google-Smtp-Source: APXvYqxCK85qx7TVgc4ayHMqBqQu1fEB48bT/Ejqu/pcIvCt6htB12kYPwcNehS0pG/Bpv584sLPMQ== X-Received: by 2002:a1c:a849:: with SMTP id r70mr4568446wme.59.1571779940612; Tue, 22 Oct 2019 14:32:20 -0700 (PDT) Received: from little-buster ([92.184.101.100]) by smtp.gmail.com with ESMTPSA id e9sm3734535wrr.13.2019.10.22.14.32.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Oct 2019 14:32:19 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Michael Heerdegen Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87v9sgrf29.fsf@gmail.com> <87zhhsd8eq.fsf@web.de> Date: Tue, 22 Oct 2019 23:32:18 +0200 In-Reply-To: <87zhhsd8eq.fsf@web.de> (Michael Heerdegen's message of "Tue, 22 Oct 2019 18:58:21 +0200") Message-ID: <87imogtqjh.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: 35564@debbugs.gnu.org, Noam Postavsky , Juri Linkov , Stefan Monnier , Eli Zaretskii , Drew Adams X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Michael Heerdegen writes: > Without having had a look yet - your last version addresses everything > brought up so far and can be considered final, right? I think so. Going over for bug#28969 and bug#35564, here are the discussion points I could identify: - y-or-n-p propertizing its prompt rigidly: out of scope, since we use read-multiple-choice now. - The prompt getting too long: it's now much shorter than the four(!)-line version I came up with in v4; it concisely spells out the issue (some characters will not be substituted) and invites the user to ask for more details if needed. - Asking the user whether they'd like to actually substitute these characters: out of scope; not sure it's necessary, since the new "details" buffer explains how to work around this for '?' (using backquotes). (Though no such workaround exists for '*'. Allowing '*' to be isolated with backquotes just like '?' would be a natural thing to do IMO, but that's unrelated to fixing this confusing prompt.) - Ensuring accessibility: users who cannot distinguish the 'warning' face are now invited to add optional '^' markers. - Preventing '`' being linked to the backquote macro in the docstring for dired-do-shell-command: still no idea how to fix that, but that can be investigated independently. Here are some remaining issues I can think of: - The code that toggles the '^' markers does not check that the command is not wrapped/truncated (i.e. that the window is wide enough). - The details window might not be tall enough, in which case maybe I should add [f]orward-/[b]ackward-page actions like nsm.el does. - In dired--no-subst-confirm, I did my best to make the window-popping dance as graceful as possible (unwind-protect so that the details buffer is killed even after C-g, save-window-excursion to restore the window configuration=E2=80=A6), but maybe it falls apart in cases I haven= 't considered. - UI bikeshedding: maybe drop the leading "Warning:", add the underline face to the mix=E2=80=A6 - Code quality: some of the small functions I wrote exist for no other reason than I found the resulting code to be easier to follow; they could probably be inlined if others do not share my preferences. From debbugs-submit-bounces@debbugs.gnu.org Sun Oct 27 18:03:06 2019 Received: (at 35564) by debbugs.gnu.org; 27 Oct 2019 22:03:06 +0000 Received: from localhost ([127.0.0.1]:43608 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iOqcr-0004sA-TX for submit@debbugs.gnu.org; Sun, 27 Oct 2019 18:03:06 -0400 Received: from crocodile.ash.relay.mailchannels.net ([23.83.222.45]:14282) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iOqcp-0004rR-Dy for 35564@debbugs.gnu.org; Sun, 27 Oct 2019 18:03:04 -0400 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id C7EFB501318; Sun, 27 Oct 2019 22:02:59 +0000 (UTC) Received: from pdx1-sub0-mail-a38.g.dreamhost.com (100-96-6-174.trex.outbound.svc.cluster.local [100.96.6.174]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 4A766501305; Sun, 27 Oct 2019 22:02:59 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from pdx1-sub0-mail-a38.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.18.5); Sun, 27 Oct 2019 22:02:59 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Absorbed-Stop: 44fdabac3cde7025_1572213779584_2063188612 X-MC-Loop-Signature: 1572213779584:671906320 X-MC-Ingress-Time: 1572213779584 Received: from pdx1-sub0-mail-a38.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a38.g.dreamhost.com (Postfix) with ESMTP id D3F2D8400B; Sun, 27 Oct 2019 15:02:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; s=linkov.net; bh=zsurxG qFwZxGUECSaGMKuYIjsEU=; b=afxuhQd3RYKwK3mEVjUp4ylM3ETxXH9YlI6tVc FhprQHCO+zzJDt90vw3lNbKIdTr8+KtkVil1MDeb32U7cwTLBbZykDZRqrZJ10p1 1NORa76p0K7lpbGek0Y2QkqFxoILp5xnwj50Fq6iPAkIKdz1LJPSpLY1Vya1rxtD +Hn/c= Received: from mail.jurta.org (m91-129-98-153.cust.tele2.ee [91.129.98.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a38.g.dreamhost.com (Postfix) with ESMTPSA id CD8908BCD6; Sun, 27 Oct 2019 15:02:47 -0700 (PDT) X-DH-BACKEND: pdx1-sub0-mail-a38 From: Juri Linkov To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters Organization: LINKOV.NET References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87v9sgrf29.fsf@gmail.com> <87d0eoseax.fsf@mail.linkov.net> <87mudstrir.fsf@gmail.com> Date: Sun, 27 Oct 2019 23:40:43 +0200 In-Reply-To: <87mudstrir.fsf@gmail.com> (=?iso-8859-1?Q?=22K=E9vin?= Le Gouguec"'s message of "Tue, 22 Oct 2019 23:11:08 +0200") Message-ID: <87a79l7vk4.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier , Eli Zaretskii , Drew Adams X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) >> 1. Why there is the verbose option =E2=80=9Ctoggle [D]etails=E2=80=9D >> while just =E2=80=9C[?]=E2=80=9D should be enough. For example, li= ke >> in query-replace typing =E2=80=98?=E2=80=99 displays the Help windo= w, >> just typing =E2=80=98?=E2=80=99 here could display the Dired Help. > > '?' is an automatic option added by read-multiple-choice. It pops-up a= n > autogenerated buffer repeating the prompt and showing longer > descriptions for each option. > > I would have liked '?' to show what I ended up putting in the "details" > buffer; ideally read-multiple-choice would have an optional HELP-MESSAG= E > argument that could be squeezed between the prompt and the key > description when showing the help buffer. '?' would be more preferable since this is the standard way to ask for additional information in Dired, for example, on error it shows: Dired error--type ? for details where '?' shows the details. dired-do-shell-command should do the same in its prompt. read-multiple-choice could be changed to not add its own help option when a '?' is provided in its 'choices' arg. From debbugs-submit-bounces@debbugs.gnu.org Wed Oct 30 18:55:31 2019 Received: (at 35564) by debbugs.gnu.org; 30 Oct 2019 22:55:32 +0000 Received: from localhost ([127.0.0.1]:51814 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iPwsF-0005wk-Hb for submit@debbugs.gnu.org; Wed, 30 Oct 2019 18:55:31 -0400 Received: from bird.elm.relay.mailchannels.net ([23.83.212.17]:59999) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iPwsD-0005wa-Kv for 35564@debbugs.gnu.org; Wed, 30 Oct 2019 18:55:30 -0400 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 655548C1A68; Wed, 30 Oct 2019 22:55:28 +0000 (UTC) Received: from pdx1-sub0-mail-a39.g.dreamhost.com (100-96-85-194.trex.outbound.svc.cluster.local [100.96.85.194]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id F17018C121F; Wed, 30 Oct 2019 22:55:27 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from pdx1-sub0-mail-a39.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.18.5); Wed, 30 Oct 2019 22:55:28 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Cure-Attack: 2269aeed05e3d1fb_1572476128228_1282773660 X-MC-Loop-Signature: 1572476128228:2043082443 X-MC-Ingress-Time: 1572476128228 Received: from pdx1-sub0-mail-a39.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a39.g.dreamhost.com (Postfix) with ESMTP id AA73A82B60; Wed, 30 Oct 2019 15:55:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; s=linkov.net; bh=/umRQC aieqN8qz2r5fsXE/KYWRo=; b=fGy/li3jZYvm53v+B03N9coT/SVUcqPzpGHcWq KfqF7HwYxjuSh8NJCMWxk55A9YB7ykjJQ8kvuUKRszBCB7lRBh1U0EDFkka8v3mg enIhREINW3Chp28+8exUjDZA2auAO9rIQl+y6lr9iUf5IlJgy3+RDqN5t+DODw4A ncfAk= Received: from mail.jurta.org (m91-129-101-77.cust.tele2.ee [91.129.101.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a39.g.dreamhost.com (Postfix) with ESMTPSA id BDD9482B59; Wed, 30 Oct 2019 15:55:19 -0700 (PDT) X-DH-BACKEND: pdx1-sub0-mail-a39 From: Juri Linkov To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters Organization: LINKOV.NET References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87v9sgrf29.fsf@gmail.com> <87d0eoseax.fsf@mail.linkov.net> <87mudstrir.fsf@gmail.com> <87a79l7vk4.fsf@mail.linkov.net> Date: Wed, 30 Oct 2019 23:59:36 +0200 In-Reply-To: <87a79l7vk4.fsf@mail.linkov.net> (Juri Linkov's message of "Sun, 27 Oct 2019 23:40:43 +0200") Message-ID: <8736f9ao8n.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) >>> 1. Why there is the verbose option =E2=80=9Ctoggle [D]etails=E2=80=9D >>> while just =E2=80=9C[?]=E2=80=9D should be enough. For example, l= ike >>> in query-replace typing =E2=80=98?=E2=80=99 displays the Help wind= ow, >>> just typing =E2=80=98?=E2=80=99 here could display the Dired Help. >> >> '?' is an automatic option added by read-multiple-choice. It pops-up = an >> autogenerated buffer repeating the prompt and showing longer >> descriptions for each option. >> >> I would have liked '?' to show what I ended up putting in the "details= " >> buffer; ideally read-multiple-choice would have an optional HELP-MESSA= GE >> argument that could be squeezed between the prompt and the key >> description when showing the help buffer. > > '?' would be more preferable since this is the standard way to ask > for additional information in Dired, for example, on error it shows: > > Dired error--type ? for details > > where '?' shows the details. dired-do-shell-command should do the same > in its prompt. read-multiple-choice could be changed to not add > its own help option when a '?' is provided in its 'choices' arg. I meant using the same logic as in 'read-answer': (if (assoc "help" answers) answers (append answers '(("help" ?? "show this help message")))) i.e. if '?' is provided in the function argument then use it, otherwise use the default value. From debbugs-submit-bounces@debbugs.gnu.org Mon Nov 04 01:37:05 2019 Received: (at 35564) by debbugs.gnu.org; 4 Nov 2019 06:37:05 +0000 Received: from localhost ([127.0.0.1]:35764 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iRVz7-0004NV-2h for submit@debbugs.gnu.org; Mon, 04 Nov 2019 01:37:05 -0500 Received: from mail-wr1-f49.google.com ([209.85.221.49]:36270) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iRVz5-0004Mz-1H for 35564@debbugs.gnu.org; Mon, 04 Nov 2019 01:37:03 -0500 Received: by mail-wr1-f49.google.com with SMTP id w18so15636968wrt.3 for <35564@debbugs.gnu.org>; Sun, 03 Nov 2019 22:37:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=6yhoxC/3I1rZvLDSybr7TTA4S+YmyK3jcydSN3+zy54=; b=Gh/00jbXNObYRd9OXeZXkxrewjGemvwCg53WLAN1KFlrmqQSaWjEy1drzUIYUBN/Wz tr2caeo/WG21LZsV5iTV4SHSmOxYaSOeBhjguKOaUZRhOAJOoa4T0+2D0tDTPp4o1iHd BJPzdQlEBrCpYLjzFO6AR/OZsGue+3LmFCufd8y0vL4aAWWkta/lyxF77ue9Hjqp9kxe m4pwvOuixa84AukhjzxXk+GUYbocUN6c9lls04brDnVYnIVZwm2nf3vmQsbB0ZTLPiH6 olAPInd4pEblGAFAc/5UAk44Cfvemn/ZCul7qfXVnpH/wc7kGiUyujQpcx41wIUTUDzc ZdJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=6yhoxC/3I1rZvLDSybr7TTA4S+YmyK3jcydSN3+zy54=; b=eOxVTSd38vQ502Aa0Zx5MOsldl4f2rcA1Qb/fy0ZiONbomSwIwJkRPh3bk8VBwCcEi GsXMk51aFp9lRc1jkDMsldvxwyJtAMGDvGbI4Lmyu/aocj7Q0zHXU2h3JdbywKkD1Tut Cby5DK+B9whTByGxa5dyGHkN+8GXLP6EJ/p/2UIaQtk5ULqGh4upOvUHfVH769NZg9Hx VpQYe43aqgnP0KVVHKvJu1RJvdCvU0BT4JU2G8SPjm5Bacq9JfZQG2pt+Ms7+7xVH74c 5B48Oph1ebKXcixC4OpBZD1RTjc4COGv3aHb+RDuQzbLbPwy6M/XJDJX6iysk0qA70CG 87SA== X-Gm-Message-State: APjAAAVNK5hlAZx5kyYWaJMs7Nzk7MNhRgJhXONvhqaP/G+OP0iWBymU 3oaT3ivKfZafQ16S+pawsCA= X-Google-Smtp-Source: APXvYqyo8OmDqkPUj9M2R1FaqGOKerj7LSlypqztt7Pd+XegK72HWzeAG3z636q8H9lbWCCBcDJReQ== X-Received: by 2002:a5d:414a:: with SMTP id c10mr4508331wrq.100.1572849417113; Sun, 03 Nov 2019 22:36:57 -0800 (PST) Received: from little-buster ([109.190.253.11]) by smtp.gmail.com with ESMTPSA id z15sm15463251wrr.19.2019.11.03.22.36.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Nov 2019 22:36:55 -0800 (PST) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Juri Linkov Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87v9sgrf29.fsf@gmail.com> <87d0eoseax.fsf@mail.linkov.net> <87mudstrir.fsf@gmail.com> <87a79l7vk4.fsf@mail.linkov.net> <8736f9ao8n.fsf@mail.linkov.net> Date: Mon, 04 Nov 2019 07:36:53 +0100 In-Reply-To: <8736f9ao8n.fsf@mail.linkov.net> (Juri Linkov's message of "Wed, 30 Oct 2019 23:59:36 +0200") Message-ID: <87bltscflm.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Juri Linkov writes: >> '?' would be more preferable since this is the standard way to ask >> for additional information in Dired, for example, on error it shows: >> >> Dired error--type ? for details >> >> where '?' shows the details. dired-do-shell-command should do the same >> in its prompt. read-multiple-choice could be changed to not add >> its own help option when a '?' is provided in its 'choices' arg. > > I meant using the same logic as in 'read-answer': > > (if (assoc "help" answers) > answers > (append answers '(("help" ?? "show this help message")))) > > i.e. if '?' is provided in the function argument then use it, > otherwise use the default value. I'd like to keep read-multiple-choice's built-in help action available though, I find it quite ergonomic. Plus, the fact that it is bound to ? and C-h makes it consistent with help-for-help, another command whose purpose is to describe prompt bindings in more details. Here are the ways forward I can see: 1. keep 'd' for "details" (a la nsm.el), 2. use 'h' for "help": more intuitive for "what the ftok is going on" reactions, though perhaps confusing when shown alongside '?', 3. teach read-multiple-choice to let go of '?', and=E2=80=A6 3.1. that's it; give up on the bindings-explaining help buffer, 3.2. move the code generating this buffer to an external function, which callers could re-use to fill in their own help buffer, 4. add a third, optional argument to read-multiple-choice (e.g. help-text) that would be added to the help buffer (e.g. squeezed between the prompt and the bindings). Ranked according to my preference: 1. (keeping "help" mnemonics (?, C-h) for "what can I do" actions, and "details/description/debug" mnemonics for "give more context" actions) 4. (reduces the number of actions for this specific prompt) 3.2. (same, only more involved) 3.1. (sad to give up on the bindings description) 2. (see rationale for 1; plus 'h' and '?' doing different things might be confusing) Tell me if there are other solutions I missed, or if you find any of these satisfying! Thank you for your time, and for the review. From debbugs-submit-bounces@debbugs.gnu.org Tue Nov 05 17:58:35 2019 Received: (at 35564) by debbugs.gnu.org; 5 Nov 2019 22:58:35 +0000 Received: from localhost ([127.0.0.1]:39182 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iS7mU-0004wg-V8 for submit@debbugs.gnu.org; Tue, 05 Nov 2019 17:58:35 -0500 Received: from anteater.elm.relay.mailchannels.net ([23.83.212.3]:17375) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iS7mT-0004wX-NW for 35564@debbugs.gnu.org; Tue, 05 Nov 2019 17:58:34 -0500 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 85F2C3C0F11; Tue, 5 Nov 2019 22:58:32 +0000 (UTC) Received: from pdx1-sub0-mail-a64.g.dreamhost.com (100-96-169-194.trex.outbound.svc.cluster.local [100.96.169.194]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 0682F3C0FFD; Tue, 5 Nov 2019 22:58:32 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from pdx1-sub0-mail-a64.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.18.5); Tue, 05 Nov 2019 22:58:32 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Left-Bottle: 54d8832a4d86fe73_1572994712276_2868942717 X-MC-Loop-Signature: 1572994712276:3709595052 X-MC-Ingress-Time: 1572994712275 Received: from pdx1-sub0-mail-a64.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a64.g.dreamhost.com (Postfix) with ESMTP id 343357F514; Tue, 5 Nov 2019 14:58:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; s=linkov.net; bh=uUArbc 41Uaivr+vhVCDlPQUgCa8=; b=b/7i5lMaATld3FZKj9fA3IUV/Xj5wauJ0htdUA WNjDo37eZusKBhP9UvumB0/CDnmpeaB6aBXy8AmmjeOGH2c/fcJuOUoO0Qo3F3Ug VTp6rszhR0jjRDSxNm2F1Z9qFGfw0eXllkFexviWgBYVd6hTE6wbi81WhMOHh/FJ lmEcA= Received: from mail.jurta.org (m91-129-101-77.cust.tele2.ee [91.129.101.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a64.g.dreamhost.com (Postfix) with ESMTPSA id A510A7F51D; Tue, 5 Nov 2019 14:58:23 -0800 (PST) X-DH-BACKEND: pdx1-sub0-mail-a64 From: Juri Linkov To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters Organization: LINKOV.NET References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87v9sgrf29.fsf@gmail.com> <87d0eoseax.fsf@mail.linkov.net> <87mudstrir.fsf@gmail.com> <87a79l7vk4.fsf@mail.linkov.net> <8736f9ao8n.fsf@mail.linkov.net> <87bltscflm.fsf@gmail.com> Date: Wed, 06 Nov 2019 00:22:43 +0200 In-Reply-To: <87bltscflm.fsf@gmail.com> (=?iso-8859-1?Q?=22K=E9vin?= Le Gouguec"'s message of "Mon, 04 Nov 2019 07:36:53 +0100") Message-ID: <878sou7yks.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > I'd like to keep read-multiple-choice's built-in help action available > though, I find it quite ergonomic. Plus, the fact that it is bound to = ? > and C-h makes it consistent with help-for-help, another command whose > purpose is to describe prompt bindings in more details. > > Here are the ways forward I can see: > > 1. keep 'd' for "details" (a la nsm.el), > > 2. use 'h' for "help": more intuitive for "what the ftok is going on" > reactions, though perhaps confusing when shown alongside '?', Indeed, providing several help keys is confusing. It should be less confusing to provide only '?' and to teach read-multiple-choice to use our help text where we could describe each supported key (y/n/etc.) and their effect explicitly. > 3. teach read-multiple-choice to let go of '?', and=E2=80=A6 > > 3.1. that's it; give up on the bindings-explaining help buffer, > > 3.2. move the code generating this buffer to an external function, > which callers could re-use to fill in their own help buffer, It seems this read-multiple-choice needs to be rewritten anyway to use the minibuffer instead of read-event. So the ability to override '?' could be added at the same time as well. From debbugs-submit-bounces@debbugs.gnu.org Thu Nov 07 17:58:37 2019 Received: (at 35564) by debbugs.gnu.org; 7 Nov 2019 22:58:37 +0000 Received: from localhost ([127.0.0.1]:44095 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iSqjd-0005gC-2m for submit@debbugs.gnu.org; Thu, 07 Nov 2019 17:58:37 -0500 Received: from cadetblue.birch.relay.mailchannels.net ([23.83.209.28]:31107) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iSqjb-0005g4-O0 for 35564@debbugs.gnu.org; Thu, 07 Nov 2019 17:58:36 -0500 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id A195F580CB9; Thu, 7 Nov 2019 22:58:34 +0000 (UTC) Received: from pdx1-sub0-mail-a69.g.dreamhost.com (100-96-8-64.trex.outbound.svc.cluster.local [100.96.8.64]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id D9631580B05; Thu, 7 Nov 2019 22:58:33 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from pdx1-sub0-mail-a69.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.18.5); Thu, 07 Nov 2019 22:58:34 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Inform-Abortive: 254431156aeb0c02_1573167514396_1152299303 X-MC-Loop-Signature: 1573167514396:3082738835 X-MC-Ingress-Time: 1573167514396 Received: from pdx1-sub0-mail-a69.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a69.g.dreamhost.com (Postfix) with ESMTP id 41FF48ACA8; Thu, 7 Nov 2019 14:58:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; s=linkov.net; bh=3N0eE8 rqo3dzWAsJaMbn7uWo8EY=; b=vnSCjJO2d//yuWG5fK7GDEjKA2Kb5PHbEgEWlR c+Q5jb+8kmTBOf4OWMYWqRnF0XDx4V8WTx0gf3u7cCfzGyNZYyJuGJZ59jkZnr2/ gi/wi8RxKiyKxuhXfq21Y8CZC357ak/coalR6zFbYQSIj6xIw3mwMLLxtGLBtbfK p4QDw= Received: from mail.jurta.org (m91-129-102-1.cust.tele2.ee [91.129.102.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a69.g.dreamhost.com (Postfix) with ESMTPSA id AE0348AA50; Thu, 7 Nov 2019 14:58:23 -0800 (PST) X-DH-BACKEND: pdx1-sub0-mail-a69 From: Juri Linkov To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters Organization: LINKOV.NET References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87v9sgrf29.fsf@gmail.com> <87d0eoseax.fsf@mail.linkov.net> <87mudstrir.fsf@gmail.com> <87a79l7vk4.fsf@mail.linkov.net> <8736f9ao8n.fsf@mail.linkov.net> <87bltscflm.fsf@gmail.com> <878sou7yks.fsf@mail.linkov.net> Date: Fri, 08 Nov 2019 00:17:27 +0200 In-Reply-To: <878sou7yks.fsf@mail.linkov.net> (Juri Linkov's message of "Wed, 06 Nov 2019 00:22:43 +0200") Message-ID: <87o8xnnxft.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > It seems this read-multiple-choice needs to be rewritten anyway > to use the minibuffer instead of read-event. So the ability > to override '?' could be added at the same time as well. A patch in bug#38076 replaces read-char-choice with read-char-from-minibuffer, and in one place in the patch it uses read-char-from-minibuffer in files--ask-user-about-large-file simply as (read-char-from-minibuffer (concat prompt " (y)es or (n)o or (l)iterally ") '(?y ?Y ?n ?N ?l ?L)) Maybe it would be much simpler to use something like (read-char-from-minibuffer (concat "1 occurrence of =E2=80=98?=E2=80=99 will not be substituted. = Proceed? (y)es or (n)o or (h)elp ") '(?y ?Y ?n ?N ?h ?H)) From debbugs-submit-bounces@debbugs.gnu.org Sun Nov 10 15:55:55 2019 Received: (at 35564) by debbugs.gnu.org; 10 Nov 2019 20:55:55 +0000 Received: from localhost ([127.0.0.1]:52595 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iTuFX-0003Km-2J for submit@debbugs.gnu.org; Sun, 10 Nov 2019 15:55:55 -0500 Received: from egyptian.birch.relay.mailchannels.net ([23.83.209.56]:14159) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iTuFW-0003Kd-5B for 35564@debbugs.gnu.org; Sun, 10 Nov 2019 15:55:54 -0500 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id C9B2458036A; Sun, 10 Nov 2019 20:55:52 +0000 (UTC) Received: from pdx1-sub0-mail-a14.g.dreamhost.com (100-96-92-150.trex.outbound.svc.cluster.local [100.96.92.150]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 5906958079D; Sun, 10 Nov 2019 20:55:52 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from pdx1-sub0-mail-a14.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.18.5); Sun, 10 Nov 2019 20:55:52 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Desert-Macabre: 357b65ca3a246734_1573419352614_1102132485 X-MC-Loop-Signature: 1573419352614:761303241 X-MC-Ingress-Time: 1573419352614 Received: from pdx1-sub0-mail-a14.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a14.g.dreamhost.com (Postfix) with ESMTP id ECB139633F; Sun, 10 Nov 2019 12:55:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; s=linkov.net; bh=mKYkbm lCbbqse8DYJGbq/AV6eJ0=; b=ahs2uiIpXFI3CuKuX1VvKiq6T85RIVw42jnr46 W1ZXS5G7zXyyMSW4lR5JWBRMXBVIKtR5omlDGHGbZrKTBmyBPiq7S7F6YnEqD6D/ Y46kF7GPWrRpQSN0bMDAnXErbVYYydukoESQdsEsqWqh37P2TDWISE+C1W+G4h9E vd3yI= Received: from mail.jurta.org (m91-129-102-1.cust.tele2.ee [91.129.102.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a14.g.dreamhost.com (Postfix) with ESMTPSA id 9DAF49872B; Sun, 10 Nov 2019 12:55:43 -0800 (PST) X-DH-BACKEND: pdx1-sub0-mail-a14 From: Juri Linkov To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters Organization: LINKOV.NET References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87v9sgrf29.fsf@gmail.com> <87d0eoseax.fsf@mail.linkov.net> <87mudstrir.fsf@gmail.com> <87a79l7vk4.fsf@mail.linkov.net> <8736f9ao8n.fsf@mail.linkov.net> <87bltscflm.fsf@gmail.com> <878sou7yks.fsf@mail.linkov.net> <87o8xnnxft.fsf@mail.linkov.net> Date: Sun, 10 Nov 2019 22:18:27 +0200 In-Reply-To: <87o8xnnxft.fsf@mail.linkov.net> (Juri Linkov's message of "Fri, 08 Nov 2019 00:17:27 +0200") Message-ID: <87imnr3bhw.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > A patch in bug#38076 replaces read-char-choice with > read-char-from-minibuffer, and in one place in the patch > it uses read-char-from-minibuffer in files--ask-user-about-large-file > simply as > > (read-char-from-minibuffer > (concat prompt " (y)es or (n)o or (l)iterally ") > '(?y ?Y ?n ?N ?l ?L)) > > Maybe it would be much simpler to use something like > > (read-char-from-minibuffer > (concat "1 occurrence of =E2=80=98?=E2=80=99 will not be substituted.= Proceed? (y)es or (n)o or (h)elp ") > '(?y ?Y ?n ?N ?h ?H)) A better example is ask-user-about-supersession-threat in userlock.el that using read-char-from-minibuffer displays such prompt: file changed on disk; really edit the buffer? (y, n, r or C-h)=20 Please use a similarly short prompt: 1 occurrence of =E2=80=98?=E2=80=99 will not be substituted. Proceed? = (y, n or ?)=20 where '?' will show the Dired help window. This will simplify the user interface to make it less confusing (no more choice for two separate help texts). From debbugs-submit-bounces@debbugs.gnu.org Sun Nov 10 15:56:08 2019 Received: (at 35564) by debbugs.gnu.org; 10 Nov 2019 20:56:08 +0000 Received: from localhost ([127.0.0.1]:52601 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iTuFk-0003Lp-BO for submit@debbugs.gnu.org; Sun, 10 Nov 2019 15:56:08 -0500 Received: from chocolate.birch.relay.mailchannels.net ([23.83.209.35]:58146) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iTuFf-0003LW-LZ for 35564@debbugs.gnu.org; Sun, 10 Nov 2019 15:56:04 -0500 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 46E68E0B51; Sun, 10 Nov 2019 20:56:02 +0000 (UTC) Received: from pdx1-sub0-mail-a14.g.dreamhost.com (100-96-92-150.trex.outbound.svc.cluster.local [100.96.92.150]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 5EAF6E0B40; Sun, 10 Nov 2019 20:56:01 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from pdx1-sub0-mail-a14.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.18.5); Sun, 10 Nov 2019 20:56:02 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Supply-Whispering: 45c856c44e2380cc_1573419362029_431900614 X-MC-Loop-Signature: 1573419362029:1724492421 X-MC-Ingress-Time: 1573419362029 Received: from pdx1-sub0-mail-a14.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a14.g.dreamhost.com (Postfix) with ESMTP id 008DF9633F; Sun, 10 Nov 2019 12:55:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; s=linkov.net; bh=jGuUAo ffFXfHp2GssE2g+FZiRM0=; b=3bcXrEjGvO+yHf6/H9j8VWWk+YUqZSBT59Ec4n RP1wZ1ULkUgcwYSzx/IA+usZl27s4RTz29dE79Rk5zDN78bbyknUq6IiNYW/H1f2 iNB2DJ8dH414QVwGvB8yz2eOxDxYQ8ZnjZQkPF0Sr83vD3cQIURZTl1dsXgZZDQT pqhqc= Received: from mail.jurta.org (m91-129-102-1.cust.tele2.ee [91.129.102.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a14.g.dreamhost.com (Postfix) with ESMTPSA id BB5099872B; Sun, 10 Nov 2019 12:55:50 -0800 (PST) X-DH-BACKEND: pdx1-sub0-mail-a14 From: Juri Linkov To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters Organization: LINKOV.NET References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87v9sgrf29.fsf@gmail.com> <87zhhsd8eq.fsf@web.de> <87imogtqjh.fsf@gmail.com> Date: Sun, 10 Nov 2019 22:29:34 +0200 In-Reply-To: <87imogtqjh.fsf@gmail.com> (=?iso-8859-1?Q?=22K=E9vin?= Le Gouguec"'s message of "Tue, 22 Oct 2019 23:22:18 +0200") Message-ID: <87eeyf3bg1.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier , Eli Zaretskii , Drew Adams X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > Going over for bug#28969 and bug#35564, here are the > discussion points I could identify: It seems all these points are resolved now: > - y-or-n-p propertizing its prompt rigidly: out of scope, since we use > read-multiple-choice now. y-or-n-p doesn't propertize its prompt rigidly now, but indeed this is out of scope when using read-char-from-minibuffer. > - The prompt getting too long: it's now much shorter than the > four(!)-line version I came up with in v4; it concisely spells out th= e > issue (some characters will not be substituted) and invites the user > to ask for more details if needed. Please use a shorter prompt like 1 occurrence of =E2=80=98?=E2=80=99 will not be substituted. Proceed? = (y, n or ?)=20 > - Asking the user whether they'd like to actually substitute these > characters: out of scope; not sure it's necessary, since the new > "details" buffer explains how to work around this for '?' (using > backquotes). Displaying the new "Dired help" buffer on demand is a good idea. > - Ensuring accessibility: users who cannot distinguish the 'warning' > face are now invited to add optional '^' markers. In the new "Dired help" buffer where there is enough space to add the command line with '^' markers. > - Preventing '`' being linked to the backquote macro in the docstring > for dired-do-shell-command: still no idea how to fix that, but that > can be investigated independently. Maybe use double quotes "`" as an exception. > Here are some remaining issues I can think of: > > - The code that toggles the '^' markers does not check that the command > is not wrapped/truncated (i.e. that the window is wide enough). Everything should be explained in the new "Dired help" buffer including the command line with '^' markers. > - The details window might not be tall enough, in which case maybe I > should add [f]orward-/[b]ackward-page actions like nsm.el does. Yesterday I added new keybindings C-v/M-v for scrolling the original window from the minibuffer. > - In dired--no-subst-confirm, I did my best to make the window-popping > dance as graceful as possible (unwind-protect so that the details > buffer is killed even after C-g, save-window-excursion to restore the > window configuration=E2=80=A6), but maybe it falls apart in cases I h= aven't > considered. Maybe some of the standard display-window functions can handle this, but this is a minor question. > - UI bikeshedding: maybe drop the leading "Warning:" Right, this makes the prompt shorter. From debbugs-submit-bounces@debbugs.gnu.org Thu Nov 14 02:03:01 2019 Received: (at 35564) by debbugs.gnu.org; 14 Nov 2019 07:03:02 +0000 Received: from localhost ([127.0.0.1]:60823 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iV99h-0003v1-CO for submit@debbugs.gnu.org; Thu, 14 Nov 2019 02:03:01 -0500 Received: from mail-wm1-f52.google.com ([209.85.128.52]:36834) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iV99g-0003uo-22 for 35564@debbugs.gnu.org; Thu, 14 Nov 2019 02:03:00 -0500 Received: by mail-wm1-f52.google.com with SMTP id c22so4622995wmd.1 for <35564@debbugs.gnu.org>; Wed, 13 Nov 2019 23:02:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=xfeVxSVPzwQTGG8VPkYdvqyr11w4Ra5BQ0ip+IYjZT4=; b=li4+fD7V6twPqrPA7T15vsSBE3WbxfzzCTOOui3WaF/8fNIHxOPiaoutZ7II7idO/b FD2kKJSp4vpaTQvEiqc0OM7s4pU+eVccRktRv/vYhrKOa468BbewlfO5UUFYNB+TzfC+ 0K0l53KEz+byPWtd+mGpULIAdGHZ+zXlhUXuwhWRPubRmgbRc6ylk8e27phct3zxVV8O pLSoSlLpC0gb7w239n7QrN6KgSDTQLts3k5Femra7YdsAardj2AsgWRxecE2e9lwzdHr xq1tivy2tJCyxuQ/KL8mwXkQjcwXhIMeS2q/SbnSrCIrSO9jmvtmCHf7ibke+gFkifFK MCiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=xfeVxSVPzwQTGG8VPkYdvqyr11w4Ra5BQ0ip+IYjZT4=; b=etRuKYrbA9J4kpPfQAWa7s/I0Z1m9CRDeeicN4UpQXBqaP0Y0gF8ZOYZI4HQmQiY7Z cS7h13XgsQGZhu5zGKvk7v9CJy6mjO0n0rTce1HfDZJ4xJkC62jEPYKCzXOm35ThY8+U 8SeGbdNXnk0Bs5BchV6qOaejAGRsvCx5GZ64In7FxOvjTf8dAFtyzhqGafTcBe81y7f1 5aV3l32I5tznWCDxTtb3MOH5XDZ7SoCsvK8I+ePv+Fbs6CMkicmHvDmFQJvT+7gOk0dl /7PjyeVuUHbSUbg9FEdnpIMuca01STS2CDtEJOTnXwKTpCyHvAGkd4upx8oQKQYn+J4w VVIg== X-Gm-Message-State: APjAAAWlY+CJTea4SVDLu60wgO8f4Pax58sHmKYfVMh7Bzb4IsO3Cepe Z+AfprMi/+wnOEtZzj1FMOQ= X-Google-Smtp-Source: APXvYqy1YJvApaWZhCqmxqQWuSdPgxqKtINaFTWlGsSwHZ9KGdCmFrh6A5FEIod7YBOKH0VtV1KUOA== X-Received: by 2002:a1c:b1d4:: with SMTP id a203mr5844326wmf.160.1573714974076; Wed, 13 Nov 2019 23:02:54 -0800 (PST) Received: from my-little-tumbleweed (200.143.13.109.rev.sfr.net. [109.13.143.200]) by smtp.gmail.com with ESMTPSA id a11sm5208527wmh.40.2019.11.13.23.02.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Nov 2019 23:02:53 -0800 (PST) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Juri Linkov Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87v9sgrf29.fsf@gmail.com> <87zhhsd8eq.fsf@web.de> <87imogtqjh.fsf@gmail.com> <87eeyf3bg1.fsf@mail.linkov.net> Date: Thu, 14 Nov 2019 08:02:52 +0100 In-Reply-To: <87eeyf3bg1.fsf@mail.linkov.net> (Juri Linkov's message of "Sun, 10 Nov 2019 22:29:34 +0200") Message-ID: <87d0dv7xer.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier , Eli Zaretskii , Drew Adams X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Thanks for your input Juri. I see that your work on read-char-from-minibuffer has been pushed to master; I'll start working on a v6 using that function instead of read-multiple-choice ASAP. Juri Linkov writes: > Please use a shorter prompt like > > 1 occurrence of =E2=80=98?=E2=80=99 will not be substituted. Proceed? = (y, n or ?)=20 Will do. > In the new "Dired help" buffer where there is enough space to add > the command line with '^' markers. Note that the current implementation is quite naive: it falls apart if the command is wider than the help window. E.g.: some-command "first?argument" "sec=E2=A4=B8 =E2=A4=B9ond?argument" "final-argument" ^ =E2=A4=B8 =E2=A4=B9 ^ (=E2=A4=B8 and =E2=A4=B9 represent fringe indicators for wrapped lines.) I don't know how important it is to handle this situation, since read-char-from-minibuffer allows C-x o'ing to the help buffer and toggling truncated lines. >> - Preventing '`' being linked to the backquote macro in the docstring >> for dired-do-shell-command: still no idea how to fix that, but that >> can be investigated independently. > > Maybe use double quotes "`" as an exception. Maybe. The docstring single-quotes every other character it mentions though (?, *, &, ;), so that would look sort of inconsistent. Note that this problem also impacts other docstrings[1]. >> - The details window might not be tall enough, in which case maybe I >> should add [f]orward-/[b]ackward-page actions like nsm.el does. > > Yesterday I added new keybindings C-v/M-v for scrolling the original > window from the minibuffer. Nice! (Out of curiosity, would it make sense to also bind C-x < and C-x >?) >> - UI bikeshedding: maybe drop the leading "Warning:" > > Right, this makes the prompt shorter. Will do then. Again, thank you for your time. [1] subr.el:372:like `%', `\\=3D`' and `\\=3D'', use (error \"%s\" MESSAGE). subr.el:388:like `%', `\\=3D`' and `\\=3D'', use (error \"%s\" MESSAGE). emulation/viper-util.el:1173:symbols like `\\=3D`', `\\=3D'', `:', `\"', `)= ', and `{' are excluded. leim/quail/cyrillic.el:1362:`]', `\\', `\\=3D`' and `[' keys respectively, = Caps Lock does not affect them." leim/quail/hebrew.el:116: `\\=3D`' is used to switch levels instead of Alt-= Gr. leim/quail/hebrew.el:606: `\\=3D`' is used to switch levels instead of Alt-= Gr. leim/quail/thai.el:50: `=E0=B8=83' and `=E0=B8=85' are assigned to `\\= =3D`' and `~' respectively, Note also that there are places where this works as intended: emacs-lisp/backquote.el:253: "See `\\=3D`' (also `pcase') for the usage= of `,'.") emacs-lisp/backquote.el:257: "See `\\=3D`' for the usage of `,@'.") From debbugs-submit-bounces@debbugs.gnu.org Sat Nov 16 16:07:26 2019 Received: (at 35564) by debbugs.gnu.org; 16 Nov 2019 21:07:26 +0000 Received: from localhost ([127.0.0.1]:39776 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iW5Hy-0005iP-1N for submit@debbugs.gnu.org; Sat, 16 Nov 2019 16:07:26 -0500 Received: from chocolate.birch.relay.mailchannels.net ([23.83.209.35]:25390) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iW5Hw-0005iD-TB for 35564@debbugs.gnu.org; Sat, 16 Nov 2019 16:07:25 -0500 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id E18B91410B2; Sat, 16 Nov 2019 21:07:23 +0000 (UTC) Received: from pdx1-sub0-mail-a75.g.dreamhost.com (100-96-86-105.trex.outbound.svc.cluster.local [100.96.86.105]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 43876140FED; Sat, 16 Nov 2019 21:07:23 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from pdx1-sub0-mail-a75.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.18.5); Sat, 16 Nov 2019 21:07:23 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Company-Troubled: 2102b7e16e73daa6_1573938443548_861136656 X-MC-Loop-Signature: 1573938443548:4240155948 X-MC-Ingress-Time: 1573938443547 Received: from pdx1-sub0-mail-a75.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a75.g.dreamhost.com (Postfix) with ESMTP id 4ABD67F705; Sat, 16 Nov 2019 13:07:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; s=linkov.net; bh=yBkPzL Ahaf+kowKZbAVSt3zyYio=; b=J7C145M3w8iflXRTPDuDvo23H0vOk6yZklOzye 7Q3Dp9Fl39cS2wLWti8cNHt5WocpM/pCKagNo7NFjbLWClXP5ZksSotLZTsKjKcJ u9q/Wx9aMC4xn5v9rdYejcMnGBjfxdReBe0cvPISLiT+pPpU5X7Hxps3VlDJASFf JA/HA= Received: from mail.jurta.org (m91-129-102-1.cust.tele2.ee [91.129.102.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a75.g.dreamhost.com (Postfix) with ESMTPSA id 021777F702; Sat, 16 Nov 2019 13:07:16 -0800 (PST) X-DH-BACKEND: pdx1-sub0-mail-a75 From: Juri Linkov To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters Organization: LINKOV.NET References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87v9sgrf29.fsf@gmail.com> <87zhhsd8eq.fsf@web.de> <87imogtqjh.fsf@gmail.com> <87eeyf3bg1.fsf@mail.linkov.net> <87d0dv7xer.fsf@gmail.com> Date: Sat, 16 Nov 2019 22:23:56 +0200 In-Reply-To: <87d0dv7xer.fsf@gmail.com> (=?iso-8859-1?Q?=22K=E9vin?= Le Gouguec"'s message of "Thu, 14 Nov 2019 08:02:52 +0100") Message-ID: <87zhgvsonz.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier , Eli Zaretskii , Drew Adams X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) >> In the new "Dired help" buffer where there is enough space to add >> the command line with '^' markers. > > Note that the current implementation is quite naive: it falls apart if > the command is wider than the help window. E.g.: > > some-command "first?argument" "sec=E2=A4=B8 > =E2=A4=B9ond?argument" "final-argument" > ^ =E2=A4=B8 > =E2=A4=B9 ^ > > (=E2=A4=B8 and =E2=A4=B9 represent fringe indicators for wrapped lines.= ) > > I don't know how important it is to handle this situation, since > read-char-from-minibuffer allows C-x o'ing to the help buffer and > toggling truncated lines. Or truncated lines could be enabled by default in the "Dired help" buffer by using (setq truncate-lines nil) >>> - The details window might not be tall enough, in which case maybe I >>> should add [f]orward-/[b]ackward-page actions like nsm.el does. >> >> Yesterday I added new keybindings C-v/M-v for scrolling the original >> window from the minibuffer. > > Nice! > (Out of curiosity, would it make sense to also bind C-x < and C-x >?) Wouldn't =E2=80=98C-x <=E2=80=99 and =E2=80=98C-x >=E2=80=99 be more need= ed to scroll the minibuffer horizontally? I tried to toggle truncated lines in the minibuffer, and then =E2=80=98C-x <=E2=80=99 and =E2=80=98C-x >=E2=80=99 scroll the m= inibuffer horizontally. From debbugs-submit-bounces@debbugs.gnu.org Wed Dec 18 02:11:40 2019 Received: (at 35564) by debbugs.gnu.org; 18 Dec 2019 07:11:40 +0000 Received: from localhost ([127.0.0.1]:42612 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ihTUf-0004r3-OW for submit@debbugs.gnu.org; Wed, 18 Dec 2019 02:11:40 -0500 Received: from mail-wr1-f54.google.com ([209.85.221.54]:46414) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ihTUb-0004qk-BC for 35564@debbugs.gnu.org; Wed, 18 Dec 2019 02:11:36 -0500 Received: by mail-wr1-f54.google.com with SMTP id z7so998749wrl.13 for <35564@debbugs.gnu.org>; Tue, 17 Dec 2019 23:11:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=Gz+YKUpadtrqDTjkGm2ZwrRfm30gSo6QKPSWWbXsmcI=; b=MLcrouOc8fnnVRbtBUoD/TVUczz0c87PY+TD3uW4wXjORIb3oBwRHs3NdQ/b3twbci iWheqKKVcce6uOOmHPwjqv3tVHoKEt3+9S7szOjy+D/h1sRCqBfT7o09huAmGMS3hlk3 2/o7Bu414l0109Mu3Fa2q2P70/6XY77f+Ma+XiSlMhcs2Oy5p6w4BeIUwlMoR6mUcIPE aKHkfIDZOrfwB22TBp1K8ypFLDmsBxISKHRkO6rb6E5LB8C1f5Cdocx5yUIXHtyDEox2 8Xr3tyCWBnhSMotQS9CzuZgIw9ENefwVf6s1pcNRmtzPQ3nOGdlnJV0GMbJ03/hgf1AS 8fNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=Gz+YKUpadtrqDTjkGm2ZwrRfm30gSo6QKPSWWbXsmcI=; b=YJbOePpf3SG+8czUBiGVnEv20X4wlM8ChFr3V1pZSHz9QEzRpEZhiufa3LoQpguYQ7 b5cAyw3FM0AVxs+VIJmF3BfEoyU38iSyYqPp+zmBXMxfhhUSSg7CZ+XJcCG2SMZOLfP5 KfyQMYvyFSeHEB+l2k59otxJyTupIgPvUbnh/C8vTn+SYl9sSDQgoW71yHO3+CBw57TF wUqPEonnSPRU9DOWUYpG13iB/SZCSYnkmBH2nne9I0X4CpTmuo8L/tt4AYAM9d3ZjEJT q0fUxk8Yly8V7L/LN9pxvOyoi4Uc27B8YyupSTIRRp2wOtnF/l8wZiqMJ0PgsGVew2SO D84g== X-Gm-Message-State: APjAAAV2E5s+tkAErGAUdsysTAKnFvxldUneLyIKkl1qWrtzsSqZpJOo zm8pQqh8nejigtApnBXKNfI= X-Google-Smtp-Source: APXvYqzOSTCUVOzHwoQfabB6E5ALgO11xL0yzHMkpoM7A2iEMiFRczY4qB0U9nI5aDFHOLJ1aEYedg== X-Received: by 2002:adf:e5cb:: with SMTP id a11mr917154wrn.28.1576653087475; Tue, 17 Dec 2019 23:11:27 -0800 (PST) Received: from my-little-tumbleweed (200.143.13.109.rev.sfr.net. [109.13.143.200]) by smtp.gmail.com with ESMTPSA id c2sm1499247wrp.46.2019.12.17.23.11.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 17 Dec 2019 23:11:26 -0800 (PST) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: 35564@debbugs.gnu.org Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> Date: Wed, 18 Dec 2019 08:11:25 +0100 In-Reply-To: <87o8yoign9.fsf_-_@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Thu, 10 Oct 2019 20:45:14 +0200") Message-ID: <87a77qhzvm.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , Noam Postavsky , Juri Linkov , Stefan Monnier , Eli Zaretskii , Drew Adams X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain Hello, Here is a new revision of this patch series, which aims to rephrase dired-do-shell-command's warning about occurrences of '?' and '*' that will not be substituted for filenames, with the following goals in mind: 1. cease to call these characters "wildcards" since they may be quoted or escaped, 2. cater to users who do not know about the substitution feature, 3. keep the default prompt as concise as the current one. The first revisions[1][2][3][4] focused on goals 1 and 2, to the detriment of 3. The last revision[5] hid the verbosity behind an optional explanatory buffer, using read-multiple-choice. Since this function already generates a help buffer bound to '?', I bound the explanatory buffer to 'd' for "details", a la nsm-query-user. Juri suggested[6] that read-char-from-minibuffer might fit the bill better. Since I feel kind of torn between these options, I'm putting them both forward. First, the scaffolding patches (same as v5): --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Tweak-dired-warning-about-wildcard-characters.patch >From 179fd2765e53c838d89a80ff3f680dccd4414293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 7 Jun 2019 17:19:44 +0200 Subject: [PATCH 1/5] Tweak dired warning about "wildcard" characters Non-isolated '?' and '*' characters may be quoted, or backslash-escaped; we do not know for a fact that the shell will interpret them as wildcards. Rephrase the prompt and highlight the characters so that the user sees exactly what we are talking about. * lisp/dired-aux.el (dired--isolated-char-p) (dired--highlight-nosubst-char, dired--no-subst-prompt): New functions. (dired-do-shell-command): Use them. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p) (dired-test-highlight-metachar): Test the new functions. (Bug#35564) --- lisp/dired-aux.el | 42 ++++++++++++++++++++++++++++++++---- test/lisp/dired-aux-tests.el | 28 ++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index fb1ad6266d..1c2a9d1555 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -79,6 +79,42 @@ dired--star-or-qmark-p (funcall (if keep #'string-match-p #'string-match) x string)) regexps))) +(defun dired--isolated-char-p (command pos) + "Assert whether the character at POS is isolated within COMMAND. +A character is isolated if: +- it is surrounded by whitespace, the start of the command, or + the end of the command, +- it is surrounded by `\\=`' characters." + (let ((start (max 0 (1- pos))) + (char (string (aref command pos)))) + (and (string-match + (rx (or (seq (or bos blank) + (group-n 1 (literal char)) + (or eos blank)) + (seq ?` (group-n 1 (literal char)) ?`))) + command start) + (= pos (match-beginning 1))))) + +(defun dired--highlight-nosubst-char (command char) + "Highlight occurences of CHAR that are not isolated in COMMAND. +These occurences will not be substituted; they will be sent as-is +to the shell, which may interpret them as wildcards." + (save-match-data + (let ((highlighted (substring-no-properties command)) + (pos 0)) + (while (string-match (regexp-quote char) command pos) + (let ((start (match-beginning 0)) + (end (match-end 0))) + (unless (dired--isolated-char-p command start) + (add-face-text-property start end 'warning nil highlighted)) + (setq pos end))) + highlighted))) + +(defun dired--no-subst-prompt (command char) + (let ((highlighted-command (dired--highlight-nosubst-char command char)) + (prompt "Confirm--the highlighted characters will not be substituted:")) + (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + ;;;###autoload (defun dired-diff (file &optional switches) "Compare file at point with FILE using `diff'. @@ -773,11 +809,9 @@ dired-do-shell-command (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((need-confirm-p command "*") - (y-or-n-p (format-message - "Confirm--do you mean to use `*' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "*"))) ((need-confirm-p command "?") - (y-or-n-p (format-message - "Confirm--do you mean to use `?' as a wildcard? "))) + (y-or-n-p (dired--no-subst-prompt command "?"))) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ccd3192792..80b6393931 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,6 +114,34 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(ert-deftest dired-test-isolated-char-p () + (should (dired--isolated-char-p "?" 0)) + (should (dired--isolated-char-p "? " 0)) + (should (dired--isolated-char-p " ?" 1)) + (should (dired--isolated-char-p " ? " 1)) + (should (dired--isolated-char-p "foo bar ? baz" 8)) + (should (dired--isolated-char-p "foo -i`?`" 7)) + (should-not (dired--isolated-char-p "foo `bar`?" 9)) + (should-not (dired--isolated-char-p "foo 'bar?'" 8)) + (should-not (dired--isolated-char-p "foo bar?baz" 7)) + (should-not (dired--isolated-char-p "foo bar?" 7))) + +(ert-deftest dired-test-highlight-metachar () + "Check that non-isolated meta-characters are highlighted" + (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (result (dired--highlight-nosubst-char command "?"))) + (should-not (text-property-not-all 1 14 'face nil result)) + (should (equal 'warning (get-text-property 15 'face result))) + (should-not (text-property-not-all 16 28 'face nil result)) + (should (equal 'warning (get-text-property 29 'face result))) + (should-not (text-property-not-all 30 39 'face nil result))) + (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") + (result (dired--highlight-nosubst-char command "*"))) + (should-not (text-property-not-all 1 10 'face nil result)) + (should (equal 'warning (get-text-property 11 'face result))) + (should-not (text-property-not-all 12 23 'face nil result)) + (should (equal 'warning (get-text-property 24 'face result))) + (should-not (text-property-not-all 25 29 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.24.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-Dedup-dired-aux-isolated-char-searching-Bug-35564.patch >From 064ec112fae60b9914b635965c5ab54b151da3b8 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 27 Jun 2019 19:15:56 -0400 Subject: [PATCH 2/5] Dedup dired-aux isolated char searching (Bug#35564) * lisp/dired-aux.el (dired-isolated-string-re): Use explicitly numbered groups. (dired--star-or-qmark-p): Add START parameter. Make sure to return the first isolated match. (dired--no-subst-prompt): Operate on a list of positions rather than searching again for isolated chars. Shorten prompt, and include the character being asked about in the question (to make it clearer, and in case the user can't see the fontification for whatever reason, e.g., screen reader). (dired--isolated-char-p): Remove. (dired--need-confirm-positions): New function. (dired-do-shell-command): Use it. * test/lisp/dired-aux-tests.el (dired-test-isolated-char-p): Remove. (dired-test-highlight-metachar): Adjust to new functions. Make sure that `*` isn't considered isolated. --- lisp/dired-aux.el | 113 ++++++++++++++++------------------- test/lisp/dired-aux-tests.el | 31 +++++----- 2 files changed, 67 insertions(+), 77 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 1c2a9d1555..6766c620f6 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -60,60 +60,60 @@ dired-isolated-string-re of a string followed/prefixed with an space. The regexp capture the preceding blank, STRING and the following blank as the groups 1, 2 and 3 respectively." - (format "\\(\\`\\|[ \t]\\)\\(%s\\)\\([ \t]\\|\\'\\)" string)) + (format "\\(?1:\\`\\|[ \t]\\)\\(?2:%s\\)\\(?3:[ \t]\\|\\'\\)" string)) -(defun dired--star-or-qmark-p (string match &optional keep) +(defun dired--star-or-qmark-p (string match &optional keep start) "Return non-nil if STRING contains isolated MATCH or `\\=`?\\=`'. MATCH should be the strings \"?\", `\\=`?\\=`', \"*\" or nil. The latter means STRING contains either \"?\" or `\\=`?\\=`' or \"*\". If optional arg KEEP is non-nil, then preserve the match data. Otherwise, this function changes it and saves MATCH as the second match group. +START is the position to start matching from. Isolated means that MATCH is surrounded by spaces or at the beginning/end of STRING followed/prefixed with an space. A match to `\\=`?\\=`', isolated or not, is also valid." - (let ((regexps (list (dired-isolated-string-re (if match (regexp-quote match) "[*?]"))))) + (let ((regexp (dired-isolated-string-re (if match (regexp-quote match) "[*?]")))) (when (or (null match) (equal match "?")) - (setq regexps (append (list "\\(\\)\\(`\\?`\\)\\(\\)") regexps))) - (cl-some (lambda (x) - (funcall (if keep #'string-match-p #'string-match) x string)) - regexps))) - -(defun dired--isolated-char-p (command pos) - "Assert whether the character at POS is isolated within COMMAND. -A character is isolated if: -- it is surrounded by whitespace, the start of the command, or - the end of the command, -- it is surrounded by `\\=`' characters." - (let ((start (max 0 (1- pos))) - (char (string (aref command pos)))) - (and (string-match - (rx (or (seq (or bos blank) - (group-n 1 (literal char)) - (or eos blank)) - (seq ?` (group-n 1 (literal char)) ?`))) - command start) - (= pos (match-beginning 1))))) - -(defun dired--highlight-nosubst-char (command char) - "Highlight occurences of CHAR that are not isolated in COMMAND. -These occurences will not be substituted; they will be sent as-is -to the shell, which may interpret them as wildcards." - (save-match-data - (let ((highlighted (substring-no-properties command)) - (pos 0)) - (while (string-match (regexp-quote char) command pos) - (let ((start (match-beginning 0)) - (end (match-end 0))) - (unless (dired--isolated-char-p command start) - (add-face-text-property start end 'warning nil highlighted)) - (setq pos end))) - highlighted))) - -(defun dired--no-subst-prompt (command char) - (let ((highlighted-command (dired--highlight-nosubst-char command char)) - (prompt "Confirm--the highlighted characters will not be substituted:")) - (format-message "%s\n%s\nProceed?" prompt highlighted-command))) + (cl-callf concat regexp "\\|\\(?1:\\)\\(?2:`\\?`\\)\\(?3:\\)")) + (funcall (if keep #'string-match-p #'string-match) regexp string start))) + +(defun dired--need-confirm-positions (command string) + "Search for non-isolated matches of STRING in COMMAND. +Return a list of positions that match STRING, but would not be +considered \"isolated\" by `dired--star-or-qmark-p'." + (cl-assert (= (length string) 1)) + (let ((start 0) + (isolated-char-positions nil) + (confirm-positions nil) + (regexp (regexp-quote string))) + ;; Collect all ? and * surrounded by spaces and `?`. + (while (dired--star-or-qmark-p command string nil start) + (push (cons (match-beginning 2) (match-end 2)) + isolated-char-positions) + (setq start (match-end 2))) + ;; Now collect any remaining ? and *. + (setq start 0) + (while (string-match regexp command start) + (unless (cl-member (match-beginning 0) isolated-char-positions + :test (lambda (pos match) + (<= (car match) pos (cdr match)))) + (push (match-beginning 0) confirm-positions)) + (setq start (match-end 0))) + confirm-positions)) + +(defun dired--no-subst-prompt (char-positions command) + (cl-callf substring-no-properties command) + (dolist (pos char-positions) + (add-face-text-property pos (1+ pos) 'warning nil command)) + (concat command "\n" + (format-message + (ngettext "Send %d occurrence of `%s' as-is to shell?" + "Send %d occurrences of `%s' as-is to shell?" + (length char-positions)) + (length char-positions) + (propertize (string (aref command (car char-positions))) + 'face 'warning)))) ;;;###autoload (defun dired-diff (file &optional switches) @@ -793,26 +793,19 @@ dired-do-shell-command (dired-read-shell-command "! on %s: " current-prefix-arg files) current-prefix-arg files))) - (cl-flet ((need-confirm-p - (cmd str) - (let ((res cmd) - (regexp (regexp-quote str))) - ;; Drop all ? and * surrounded by spaces and `?`. - (while (and (string-match regexp res) - (dired--star-or-qmark-p res str)) - (setq res (replace-match "" t t res 2))) - (string-match regexp res)))) (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) + (confirmations nil) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. - (ok (cond ((not (or on-each no-subst)) - (error "You can not combine `*' and `?' substitution marks")) - ((need-confirm-p command "*") - (y-or-n-p (dired--no-subst-prompt command "*"))) - ((need-confirm-p command "?") - (y-or-n-p (dired--no-subst-prompt command "?"))) - (t)))) + (ok (cond + ((not (or on-each no-subst)) + (error "You can not combine `*' and `?' substitution marks")) + ((setq confirmations (dired--need-confirm-positions command "*")) + (y-or-n-p (dired--no-subst-prompt confirmations command))) + ((setq confirmations (dired--need-confirm-positions command "?")) + (y-or-n-p (dired--no-subst-prompt confirmations command))) + (t)))) (cond ((not ok) (message "Command canceled")) (t (if on-each @@ -823,7 +816,7 @@ dired-do-shell-command nil file-list) ;; execute the shell command (dired-run-shell-command - (dired-shell-stuff-it command file-list nil arg)))))))) + (dired-shell-stuff-it command file-list nil arg))))))) ;; Might use {,} for bash or csh: (defvar dired-mark-prefix "" diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 80b6393931..ff18edddb6 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,34 +114,31 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) -(ert-deftest dired-test-isolated-char-p () - (should (dired--isolated-char-p "?" 0)) - (should (dired--isolated-char-p "? " 0)) - (should (dired--isolated-char-p " ?" 1)) - (should (dired--isolated-char-p " ? " 1)) - (should (dired--isolated-char-p "foo bar ? baz" 8)) - (should (dired--isolated-char-p "foo -i`?`" 7)) - (should-not (dired--isolated-char-p "foo `bar`?" 9)) - (should-not (dired--isolated-char-p "foo 'bar?'" 8)) - (should-not (dired--isolated-char-p "foo bar?baz" 7)) - (should-not (dired--isolated-char-p "foo bar?" 7))) - (ert-deftest dired-test-highlight-metachar () "Check that non-isolated meta-characters are highlighted" (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") - (result (dired--highlight-nosubst-char command "?"))) + (prompt (dired--no-subst-prompt + (dired--need-confirm-positions command "?") + command)) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 14 'face nil result)) (should (equal 'warning (get-text-property 15 'face result))) (should-not (text-property-not-all 16 28 'face nil result)) (should (equal 'warning (get-text-property 29 'face result))) (should-not (text-property-not-all 30 39 'face nil result))) - (let* ((command "sed -e 's/o*/a/' -e 's/o*/a/'") - (result (dired--highlight-nosubst-char command "*"))) + ;; Note that `?` is considered isolated, but `*` is not. + (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (prompt (dired--no-subst-prompt + (dired--need-confirm-positions command "*") + command)) + (result (and (string-match (regexp-quote command) prompt) + (match-string 0 prompt)))) (should-not (text-property-not-all 1 10 'face nil result)) (should (equal 'warning (get-text-property 11 'face result))) (should-not (text-property-not-all 12 23 'face nil result)) - (should (equal 'warning (get-text-property 24 'face result))) - (should-not (text-property-not-all 25 29 'face nil result)))) + (should (equal 'warning (get-text-property 25 'face result))) + (should-not (text-property-not-all 26 32 'face nil result)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.24.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0003-Add-markers-below-non-isolated-chars-in-dired-prompt.patch >From 2475254565c798725d724ee89e5d699342b6c818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 3 Jul 2019 21:17:57 +0200 Subject: [PATCH 3/5] Add '^' markers below non-isolated chars in dired prompt * lisp/dired-aux.el (dired--mark-positions): New function. (dired--no-subst-prompt): Use it to show chars without overly relying on highlighting. (dired-do-shell-command): When the echo area is wide enough to display the command without wrapping it, add the markers. * test/lisp/dired-aux-tests.el (dired-test-highlight-metachar): Add assertion for '^' marker positions. (Bug#35564) --- lisp/dired-aux.el | 43 +++++++++++++++++++++-------- test/lisp/dired-aux-tests.el | 53 ++++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 28 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 6766c620f6..038e1dbbed 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -102,18 +102,35 @@ dired--need-confirm-positions (setq start (match-end 0))) confirm-positions)) -(defun dired--no-subst-prompt (char-positions command) +(defun dired--mark-positions (positions) + (let ((markers (make-string + (1+ (apply #'max positions)) + ?\s))) + (dolist (pos positions) + (setf (aref markers pos) ?^)) + markers)) + +(defun dired--no-subst-prompt (char-positions command add-markers) (cl-callf substring-no-properties command) (dolist (pos char-positions) (add-face-text-property pos (1+ pos) 'warning nil command)) - (concat command "\n" - (format-message - (ngettext "Send %d occurrence of `%s' as-is to shell?" - "Send %d occurrences of `%s' as-is to shell?" - (length char-positions)) - (length char-positions) - (propertize (string (aref command (car char-positions))) - 'face 'warning)))) + ;; `y-or-n-p' adds some text to the beginning of the prompt when the + ;; user fails to answer 'y' or 'n'. The highlighted command thus + ;; cannot be put on the first line of the prompt, since the added + ;; text will shove the command to the right, and the '^' markers + ;; will become misaligned. + (apply #'concat + `("Confirm:\n" + ,command "\n" + ,@(when add-markers + (list (dired--mark-positions char-positions) "\n")) + ,(format-message + (ngettext "Send %d occurrence of `%s' as-is to shell?" + "Send %d occurrences of `%s' as-is to shell?" + (length char-positions)) + (length char-positions) + (propertize (string (aref command (car char-positions))) + 'face 'warning))))) ;;;###autoload (defun dired-diff (file &optional switches) @@ -796,15 +813,19 @@ dired-do-shell-command (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) (confirmations nil) + (short-enough (< (length command) + (window-width (minibuffer-window)))) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((setq confirmations (dired--need-confirm-positions command "*")) - (y-or-n-p (dired--no-subst-prompt confirmations command))) + (y-or-n-p (dired--no-subst-prompt confirmations command + short-enough))) ((setq confirmations (dired--need-confirm-positions command "?")) - (y-or-n-p (dired--no-subst-prompt confirmations command))) + (y-or-n-p (dired--no-subst-prompt confirmations command + short-enough))) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ff18edddb6..174c27052e 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -115,30 +115,49 @@ dired-test-bug30624 (kill-buffer buf))))) (ert-deftest dired-test-highlight-metachar () - "Check that non-isolated meta-characters are highlighted" + "Check that non-isolated meta-characters are highlighted." (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (markers " ^ ^") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "?") - command)) - (result (and (string-match (regexp-quote command) prompt) - (match-string 0 prompt)))) - (should-not (text-property-not-all 1 14 'face nil result)) - (should (equal 'warning (get-text-property 15 'face result))) - (should-not (text-property-not-all 16 28 'face nil result)) - (should (equal 'warning (get-text-property 29 'face result))) - (should-not (text-property-not-all 30 39 'face nil result))) + command + t)) + (lines (split-string prompt "\n")) + (highlit-command (nth 1 lines))) + (should (= (length lines) 4)) + (should (string-match (regexp-quote command) highlit-command)) + (should (string-match (regexp-quote markers) (nth 2 lines))) + (should-not (text-property-not-all 1 14 'face nil highlit-command)) + (should (equal 'warning (get-text-property 15 'face highlit-command))) + (should-not (text-property-not-all 16 28 'face nil highlit-command)) + (should (equal 'warning (get-text-property 29 'face highlit-command))) + (should-not (text-property-not-all 30 39 'face nil highlit-command))) ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (markers " ^ ^") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "*") - command)) - (result (and (string-match (regexp-quote command) prompt) - (match-string 0 prompt)))) - (should-not (text-property-not-all 1 10 'face nil result)) - (should (equal 'warning (get-text-property 11 'face result))) - (should-not (text-property-not-all 12 23 'face nil result)) - (should (equal 'warning (get-text-property 25 'face result))) - (should-not (text-property-not-all 26 32 'face nil result)))) + command + t)) + (lines (split-string prompt "\n")) + (highlit-command (nth 1 lines))) + (should (= (length lines) 4)) + (should (string-match (regexp-quote command) highlit-command)) + (should (string-match (regexp-quote markers) (nth 2 lines))) + (should-not (text-property-not-all 1 10 'face nil highlit-command)) + (should (equal 'warning (get-text-property 11 'face highlit-command))) + (should-not (text-property-not-all 12 23 'face nil highlit-command)) + (should (equal 'warning (get-text-property 25 'face highlit-command))) + (should-not (text-property-not-all 26 32 'face nil highlit-command))) + (let* ((command "sed 's/\\?/!/'") + (prompt (dired--no-subst-prompt + (dired--need-confirm-positions command "?") + command + nil)) + (lines (split-string prompt "\n")) + (highlit-command (nth 1 lines))) + (should (= (length lines) 3)) + (should (string-match (regexp-quote command) highlit-command)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.24.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0004-Simplify-highlighting-assertions.patch >From 853ac332fffab69523e02a6ca4957e63d9cf3544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Fri, 12 Jul 2019 16:10:54 +0200 Subject: [PATCH 4/5] Simplify highlighting assertions * test/lisp/dired-aux-tests.el (dired-test--check-highlighting): New function. (dired-test-highlight-metachar): Use it. (Bug#35564) --- test/lisp/dired-aux-tests.el | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 174c27052e..ba10c54332 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -114,6 +114,15 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(defun dired-test--check-highlighting (command positions) + (let ((start 1)) + (dolist (pos positions) + (should-not (text-property-not-all start (1- pos) 'face nil command)) + (should (equal 'warning (get-text-property pos 'face command))) + (setq start (1+ pos))) + (should-not (text-property-not-all + start (length command) 'face nil command)))) + (ert-deftest dired-test-highlight-metachar () "Check that non-isolated meta-characters are highlighted." (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") @@ -127,11 +136,7 @@ dired-test-highlight-metachar (should (= (length lines) 4)) (should (string-match (regexp-quote command) highlit-command)) (should (string-match (regexp-quote markers) (nth 2 lines))) - (should-not (text-property-not-all 1 14 'face nil highlit-command)) - (should (equal 'warning (get-text-property 15 'face highlit-command))) - (should-not (text-property-not-all 16 28 'face nil highlit-command)) - (should (equal 'warning (get-text-property 29 'face highlit-command))) - (should-not (text-property-not-all 30 39 'face nil highlit-command))) + (dired-test--check-highlighting highlit-command '(15 29))) ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") (markers " ^ ^") @@ -144,11 +149,7 @@ dired-test-highlight-metachar (should (= (length lines) 4)) (should (string-match (regexp-quote command) highlit-command)) (should (string-match (regexp-quote markers) (nth 2 lines))) - (should-not (text-property-not-all 1 10 'face nil highlit-command)) - (should (equal 'warning (get-text-property 11 'face highlit-command))) - (should-not (text-property-not-all 12 23 'face nil highlit-command)) - (should (equal 'warning (get-text-property 25 'face highlit-command))) - (should-not (text-property-not-all 26 32 'face nil highlit-command))) + (dired-test--check-highlighting highlit-command '(11 25))) (let* ((command "sed 's/\\?/!/'") (prompt (dired--no-subst-prompt (dired--need-confirm-positions command "?") @@ -157,7 +158,8 @@ dired-test-highlight-metachar (lines (split-string prompt "\n")) (highlit-command (nth 1 lines))) (should (= (length lines) 3)) - (should (string-match (regexp-quote command) highlit-command)))) + (should (string-match (regexp-quote command) highlit-command)) + (dired-test--check-highlighting highlit-command '(8)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.24.0 --=-=-= Content-Type: text/plain Then, the patch adding read-multiple-choice (mostly the same as v5): --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0005-Hide-detailed-explanations-in-a-togglable-help-buffe-rmc.patch >From 9851fc4f223e4d2a8880aa479f10b75c75100e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 2 Oct 2019 22:04:01 +0200 Subject: [PATCH 5/5] Hide detailed explanations in a togglable help buffer * test/lisp/dired-aux-tests.el (dired-test-bug27496): (dired-test-highlight-metachar): Adapt to new prompt. * lisp/dired-aux.el (dired--no-subst-prompt): Split into... (dired--highlight-no-subst-chars): add warning face and possibly '^' markers to command, (dired--no-subst-explain): fill in help buffer with detailed explanations, (dired--no-subst-ask): setup read-multiple-choice, (dired--no-subst-confirm): loop until we know what to do. (dired-do-shell-command): Call new function 'dired--no-subst-confirm.' (bug#28969, bug#35564) --- lisp/dired-aux.el | 103 ++++++++++++++++++++++++++--------- test/lisp/dired-aux-tests.el | 39 ++++++------- 2 files changed, 96 insertions(+), 46 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 038e1dbbed..564c6931b5 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -110,27 +110,84 @@ dired--mark-positions (setf (aref markers pos) ?^)) markers)) -(defun dired--no-subst-prompt (char-positions command add-markers) +(defun dired--highlight-no-subst-chars (positions command mark) (cl-callf substring-no-properties command) - (dolist (pos char-positions) + (dolist (pos positions) (add-face-text-property pos (1+ pos) 'warning nil command)) - ;; `y-or-n-p' adds some text to the beginning of the prompt when the - ;; user fails to answer 'y' or 'n'. The highlighted command thus - ;; cannot be put on the first line of the prompt, since the added - ;; text will shove the command to the right, and the '^' markers - ;; will become misaligned. - (apply #'concat - `("Confirm:\n" - ,command "\n" - ,@(when add-markers - (list (dired--mark-positions char-positions) "\n")) - ,(format-message - (ngettext "Send %d occurrence of `%s' as-is to shell?" - "Send %d occurrences of `%s' as-is to shell?" - (length char-positions)) - (length char-positions) - (propertize (string (aref command (car char-positions))) - 'face 'warning))))) + (if mark + (concat command "\n" (dired--mark-positions positions)) + command)) + +(defun dired--no-subst-explain (buf char-positions command mark-positions) + (with-current-buffer buf + (erase-buffer) + (insert + (format-message "\ +If your command contains occurrences of `*' surrounded by +whitespace, `dired-do-shell-command' substitutes them for the +entire file list to process. Otherwise, if your command contains +occurrences of `?' surrounded by whitespace or `%s', Dired will +run the command once for each file, substituting `?' for each +file name. + +Your command contains occurrences of `%s' that will not be +substituted, and will be passed through normally to the shell. + +%s +" + "`" + (string (aref command (car char-positions))) + (dired--highlight-no-subst-chars char-positions command mark-positions))))) + +(defun dired--no-subst-ask (char nb-occur details) + (let ((hilit-char (propertize (string char) 'face 'warning))) + (car + (read-multiple-choice + (format-message + (ngettext + "%d occurrence of `%s' will not be substituted. Proceed?" + "%d occurrences of `%s' will not be substituted. Proceed?" + nb-occur) + nb-occur hilit-char) + `((?y "yes" "Send shell command without substituting.") + (?n "no" "Abort.") + (?d "toggle details" ,(format-message + "Show/hide occurrences of `%s'." hilit-char)) + ,@(when details + '((?m "toggle markers" "Show/hide `^' markers.")))))))) + +(defun dired--no-subst-confirm (char-positions command) + (let ((help-buf (get-buffer-create "*Dired help*")) + (char (aref command (car char-positions))) + (nb-occur (length char-positions)) + (done nil) + (details nil) + (markers nil) + proceed) + (unwind-protect + (save-window-excursion + (while (not done) + (cl-case (dired--no-subst-ask char nb-occur details) + (?y + (setq done t + proceed t)) + (?n + (setq done t + proceed nil)) + (?d + (if details + (progn + (quit-window nil details) + (setq details nil)) + (dired--no-subst-explain + help-buf char-positions command markers) + (setq details (display-buffer help-buf)))) + (?m + (setq markers (not markers)) + (dired--no-subst-explain + help-buf char-positions command markers))))) + (kill-buffer help-buf)) + proceed)) ;;;###autoload (defun dired-diff (file &optional switches) @@ -813,19 +870,15 @@ dired-do-shell-command (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) (confirmations nil) - (short-enough (< (length command) - (window-width (minibuffer-window)))) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((setq confirmations (dired--need-confirm-positions command "*")) - (y-or-n-p (dired--no-subst-prompt confirmations command - short-enough))) + (dired--no-subst-confirm confirmations command)) ((setq confirmations (dired--need-confirm-positions command "?")) - (y-or-n-p (dired--no-subst-prompt confirmations command - short-enough))) + (dired--no-subst-confirm confirmations command)) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ba10c54332..e1d9eefbea 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -28,7 +28,7 @@ dired-test-bug27496 (let* ((foo (make-temp-file "foo")) (files (list foo))) (unwind-protect - (cl-letf (((symbol-function 'y-or-n-p) 'error)) + (cl-letf (((symbol-function 'read-multiple-choice) 'error)) (dired temporary-file-directory) (dired-goto-file foo) ;; `dired-do-shell-command' returns nil on success. @@ -127,39 +127,36 @@ dired-test-highlight-metachar "Check that non-isolated meta-characters are highlighted." (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") (markers " ^ ^") - (prompt (dired--no-subst-prompt + (result (dired--highlight-no-subst-chars (dired--need-confirm-positions command "?") command t)) - (lines (split-string prompt "\n")) - (highlit-command (nth 1 lines))) - (should (= (length lines) 4)) - (should (string-match (regexp-quote command) highlit-command)) - (should (string-match (regexp-quote markers) (nth 2 lines))) - (dired-test--check-highlighting highlit-command '(15 29))) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(15 29))) ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") (markers " ^ ^") - (prompt (dired--no-subst-prompt + (result (dired--highlight-no-subst-chars (dired--need-confirm-positions command "*") command t)) - (lines (split-string prompt "\n")) - (highlit-command (nth 1 lines))) - (should (= (length lines) 4)) - (should (string-match (regexp-quote command) highlit-command)) - (should (string-match (regexp-quote markers) (nth 2 lines))) - (dired-test--check-highlighting highlit-command '(11 25))) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(11 25))) (let* ((command "sed 's/\\?/!/'") - (prompt (dired--no-subst-prompt + (result (dired--highlight-no-subst-chars (dired--need-confirm-positions command "?") command nil)) - (lines (split-string prompt "\n")) - (highlit-command (nth 1 lines))) - (should (= (length lines) 3)) - (should (string-match (regexp-quote command) highlit-command)) - (dired-test--check-highlighting highlit-command '(8)))) + (lines (split-string result "\n"))) + (should (= (length lines) 1)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (dired-test--check-highlighting (nth 0 lines) '(8)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.24.0 --=-=-= Content-Type: text/plain Or, the patch adding read-char-from-minibuffer: --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0005-Hide-detailed-explanations-in-a-togglable-help-buffe-rcfm.patch >From fabee1c28f5a8fbfc41c2646478b8224f63fbfe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 2 Oct 2019 22:04:01 +0200 Subject: [PATCH 5/5] Hide detailed explanations in a togglable help buffer * test/lisp/dired-aux-tests.el (dired-test-bug27496): (dired-test-highlight-metachar): Adapt to new prompt. * lisp/dired-aux.el (dired--no-subst-prompt): Split into... (dired--highlight-no-subst-chars): add warning face and possibly '^' markers to command, (dired--no-subst-explain): fill in help buffer with detailed explanations, (dired--no-subst-ask): setup read-char-from-minibuffer, (dired--no-subst-confirm): loop until we know what to do. (dired-do-shell-command): Call new function 'dired--no-subst-confirm.' (bug#28969, bug#35564) --- lisp/dired-aux.el | 101 ++++++++++++++++++++++++++--------- test/lisp/dired-aux-tests.el | 39 +++++++------- 2 files changed, 94 insertions(+), 46 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 038e1dbbed..20b056e9f1 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -110,27 +110,82 @@ dired--mark-positions (setf (aref markers pos) ?^)) markers)) -(defun dired--no-subst-prompt (char-positions command add-markers) +(defun dired--highlight-no-subst-chars (positions command mark) (cl-callf substring-no-properties command) - (dolist (pos char-positions) + (dolist (pos positions) (add-face-text-property pos (1+ pos) 'warning nil command)) - ;; `y-or-n-p' adds some text to the beginning of the prompt when the - ;; user fails to answer 'y' or 'n'. The highlighted command thus - ;; cannot be put on the first line of the prompt, since the added - ;; text will shove the command to the right, and the '^' markers - ;; will become misaligned. - (apply #'concat - `("Confirm:\n" - ,command "\n" - ,@(when add-markers - (list (dired--mark-positions char-positions) "\n")) - ,(format-message - (ngettext "Send %d occurrence of `%s' as-is to shell?" - "Send %d occurrences of `%s' as-is to shell?" - (length char-positions)) - (length char-positions) - (propertize (string (aref command (car char-positions))) - 'face 'warning))))) + (if mark + (concat command "\n" (dired--mark-positions positions)) + command)) + +(defun dired--no-subst-explain (buf char-positions command mark-positions) + (with-current-buffer buf + (erase-buffer) + (insert + (format-message "\ +If your command contains occurrences of `*' surrounded by +whitespace, `dired-do-shell-command' substitutes them for the +entire file list to process. Otherwise, if your command contains +occurrences of `?' surrounded by whitespace or `%s', Dired will +run the command once for each file, substituting `?' for each +file name. + +Your command contains occurrences of `%s' that will not be +substituted, and will be passed through normally to the shell. + +%s + +(Press ^ to %s markers below these occurrences.) +" + "`" + (string (aref command (car char-positions))) + (dired--highlight-no-subst-chars char-positions command mark-positions) + (if mark-positions "remove" "add"))))) + +(defun dired--no-subst-ask (char nb-occur details) + (let ((hilit-char (propertize (string char) 'face 'warning)) + (choices `(?y ?n ?? ,@(when details '(?^))))) + (read-char-from-minibuffer + (format-message + (ngettext + "%d occurrence of `%s' will not be substituted. Proceed? (%s) " + "%d occurrences of `%s' will not be substituted. Proceed? (%s) " + nb-occur) + nb-occur hilit-char (mapconcat #'string choices ", ")) + choices))) + +(defun dired--no-subst-confirm (char-positions command) + (let ((help-buf (get-buffer-create "*Dired help*")) + (char (aref command (car char-positions))) + (nb-occur (length char-positions)) + (done nil) + (details nil) + (markers nil) + proceed) + (unwind-protect + (save-window-excursion + (while (not done) + (cl-case (dired--no-subst-ask char nb-occur details) + (?y + (setq done t + proceed t)) + (?n + (setq done t + proceed nil)) + (?? + (if details + (progn + (quit-window nil details) + (setq details nil)) + (dired--no-subst-explain + help-buf char-positions command markers) + (setq details (display-buffer help-buf)))) + (?^ + (setq markers (not markers)) + (dired--no-subst-explain + help-buf char-positions command markers))))) + (kill-buffer help-buf)) + proceed)) ;;;###autoload (defun dired-diff (file &optional switches) @@ -813,19 +868,15 @@ dired-do-shell-command (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) (confirmations nil) - (short-enough (< (length command) - (window-width (minibuffer-window)))) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. (ok (cond ((not (or on-each no-subst)) (error "You can not combine `*' and `?' substitution marks")) ((setq confirmations (dired--need-confirm-positions command "*")) - (y-or-n-p (dired--no-subst-prompt confirmations command - short-enough))) + (dired--no-subst-confirm confirmations command)) ((setq confirmations (dired--need-confirm-positions command "?")) - (y-or-n-p (dired--no-subst-prompt confirmations command - short-enough))) + (dired--no-subst-confirm confirmations command)) (t)))) (cond ((not ok) (message "Command canceled")) (t diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ba10c54332..64a8a035da 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -28,7 +28,7 @@ dired-test-bug27496 (let* ((foo (make-temp-file "foo")) (files (list foo))) (unwind-protect - (cl-letf (((symbol-function 'y-or-n-p) 'error)) + (cl-letf (((symbol-function 'read-char-from-minibuffer) 'error)) (dired temporary-file-directory) (dired-goto-file foo) ;; `dired-do-shell-command' returns nil on success. @@ -127,39 +127,36 @@ dired-test-highlight-metachar "Check that non-isolated meta-characters are highlighted." (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") (markers " ^ ^") - (prompt (dired--no-subst-prompt + (result (dired--highlight-no-subst-chars (dired--need-confirm-positions command "?") command t)) - (lines (split-string prompt "\n")) - (highlit-command (nth 1 lines))) - (should (= (length lines) 4)) - (should (string-match (regexp-quote command) highlit-command)) - (should (string-match (regexp-quote markers) (nth 2 lines))) - (dired-test--check-highlighting highlit-command '(15 29))) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(15 29))) ;; Note that `?` is considered isolated, but `*` is not. (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") (markers " ^ ^") - (prompt (dired--no-subst-prompt + (result (dired--highlight-no-subst-chars (dired--need-confirm-positions command "*") command t)) - (lines (split-string prompt "\n")) - (highlit-command (nth 1 lines))) - (should (= (length lines) 4)) - (should (string-match (regexp-quote command) highlit-command)) - (should (string-match (regexp-quote markers) (nth 2 lines))) - (dired-test--check-highlighting highlit-command '(11 25))) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(11 25))) (let* ((command "sed 's/\\?/!/'") - (prompt (dired--no-subst-prompt + (result (dired--highlight-no-subst-chars (dired--need-confirm-positions command "?") command nil)) - (lines (split-string prompt "\n")) - (highlit-command (nth 1 lines))) - (should (= (length lines) 3)) - (should (string-match (regexp-quote command) highlit-command)) - (dired-test--check-highlighting highlit-command '(8)))) + (lines (split-string result "\n"))) + (should (= (length lines) 1)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (dired-test--check-highlighting (nth 0 lines) '(8)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.24.0 --=-=-= Content-Type: text/plain Squashed patches: --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Tweak-dired-warning-about-wildcard-characters-rmc-squashed.patch >From e0024d156a7668a3829d451a7cc3b382860662ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 18 Dec 2019 07:54:02 +0100 Subject: [PATCH] Tweak dired warning about "wildcard" characters Non-isolated '?' and '*' characters may be quoted, or backslash-escaped; we do not know for a fact that the shell will interpret them as wildcards. Rephrase the prompt and offer to highlight the characters so that the user sees exactly what we are talking about. * lisp/dired-aux.el (dired-isolated-string-re): Use explicitly numbered groups. (dired--star-or-qmark-p): Add START parameter. Make sure to return the first isolated match. (dired--need-confirm-positions, dired--mark-positions) (dired--highlight-no-subst-chars, dired--no-subst-explain) (dired--no-subst-ask, dired--no-subst-confirm): New functions. (dired-do-shell-command): Use them. * test/lisp/dired-aux-tests.el (dired-test-bug27496): Adapt to new prompt. (dired-test--check-highlighting): New test helper. (dired-test-highlight-metachar): New tests. Co-authored-by: Noam Postavsky (bug#28969, bug#35564) --- lisp/dired-aux.el | 153 +++++++++++++++++++++++++++++------ test/lisp/dired-aux-tests.el | 45 ++++++++++- 2 files changed, 171 insertions(+), 27 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index fb1ad6266d..564c6931b5 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -60,24 +60,134 @@ dired-isolated-string-re of a string followed/prefixed with an space. The regexp capture the preceding blank, STRING and the following blank as the groups 1, 2 and 3 respectively." - (format "\\(\\`\\|[ \t]\\)\\(%s\\)\\([ \t]\\|\\'\\)" string)) + (format "\\(?1:\\`\\|[ \t]\\)\\(?2:%s\\)\\(?3:[ \t]\\|\\'\\)" string)) -(defun dired--star-or-qmark-p (string match &optional keep) +(defun dired--star-or-qmark-p (string match &optional keep start) "Return non-nil if STRING contains isolated MATCH or `\\=`?\\=`'. MATCH should be the strings \"?\", `\\=`?\\=`', \"*\" or nil. The latter means STRING contains either \"?\" or `\\=`?\\=`' or \"*\". If optional arg KEEP is non-nil, then preserve the match data. Otherwise, this function changes it and saves MATCH as the second match group. +START is the position to start matching from. Isolated means that MATCH is surrounded by spaces or at the beginning/end of STRING followed/prefixed with an space. A match to `\\=`?\\=`', isolated or not, is also valid." - (let ((regexps (list (dired-isolated-string-re (if match (regexp-quote match) "[*?]"))))) + (let ((regexp (dired-isolated-string-re (if match (regexp-quote match) "[*?]")))) (when (or (null match) (equal match "?")) - (setq regexps (append (list "\\(\\)\\(`\\?`\\)\\(\\)") regexps))) - (cl-some (lambda (x) - (funcall (if keep #'string-match-p #'string-match) x string)) - regexps))) + (cl-callf concat regexp "\\|\\(?1:\\)\\(?2:`\\?`\\)\\(?3:\\)")) + (funcall (if keep #'string-match-p #'string-match) regexp string start))) + +(defun dired--need-confirm-positions (command string) + "Search for non-isolated matches of STRING in COMMAND. +Return a list of positions that match STRING, but would not be +considered \"isolated\" by `dired--star-or-qmark-p'." + (cl-assert (= (length string) 1)) + (let ((start 0) + (isolated-char-positions nil) + (confirm-positions nil) + (regexp (regexp-quote string))) + ;; Collect all ? and * surrounded by spaces and `?`. + (while (dired--star-or-qmark-p command string nil start) + (push (cons (match-beginning 2) (match-end 2)) + isolated-char-positions) + (setq start (match-end 2))) + ;; Now collect any remaining ? and *. + (setq start 0) + (while (string-match regexp command start) + (unless (cl-member (match-beginning 0) isolated-char-positions + :test (lambda (pos match) + (<= (car match) pos (cdr match)))) + (push (match-beginning 0) confirm-positions)) + (setq start (match-end 0))) + confirm-positions)) + +(defun dired--mark-positions (positions) + (let ((markers (make-string + (1+ (apply #'max positions)) + ?\s))) + (dolist (pos positions) + (setf (aref markers pos) ?^)) + markers)) + +(defun dired--highlight-no-subst-chars (positions command mark) + (cl-callf substring-no-properties command) + (dolist (pos positions) + (add-face-text-property pos (1+ pos) 'warning nil command)) + (if mark + (concat command "\n" (dired--mark-positions positions)) + command)) + +(defun dired--no-subst-explain (buf char-positions command mark-positions) + (with-current-buffer buf + (erase-buffer) + (insert + (format-message "\ +If your command contains occurrences of `*' surrounded by +whitespace, `dired-do-shell-command' substitutes them for the +entire file list to process. Otherwise, if your command contains +occurrences of `?' surrounded by whitespace or `%s', Dired will +run the command once for each file, substituting `?' for each +file name. + +Your command contains occurrences of `%s' that will not be +substituted, and will be passed through normally to the shell. + +%s +" + "`" + (string (aref command (car char-positions))) + (dired--highlight-no-subst-chars char-positions command mark-positions))))) + +(defun dired--no-subst-ask (char nb-occur details) + (let ((hilit-char (propertize (string char) 'face 'warning))) + (car + (read-multiple-choice + (format-message + (ngettext + "%d occurrence of `%s' will not be substituted. Proceed?" + "%d occurrences of `%s' will not be substituted. Proceed?" + nb-occur) + nb-occur hilit-char) + `((?y "yes" "Send shell command without substituting.") + (?n "no" "Abort.") + (?d "toggle details" ,(format-message + "Show/hide occurrences of `%s'." hilit-char)) + ,@(when details + '((?m "toggle markers" "Show/hide `^' markers.")))))))) + +(defun dired--no-subst-confirm (char-positions command) + (let ((help-buf (get-buffer-create "*Dired help*")) + (char (aref command (car char-positions))) + (nb-occur (length char-positions)) + (done nil) + (details nil) + (markers nil) + proceed) + (unwind-protect + (save-window-excursion + (while (not done) + (cl-case (dired--no-subst-ask char nb-occur details) + (?y + (setq done t + proceed t)) + (?n + (setq done t + proceed nil)) + (?d + (if details + (progn + (quit-window nil details) + (setq details nil)) + (dired--no-subst-explain + help-buf char-positions command markers) + (setq details (display-buffer help-buf)))) + (?m + (setq markers (not markers)) + (dired--no-subst-explain + help-buf char-positions command markers))))) + (kill-buffer help-buf)) + proceed)) ;;;###autoload (defun dired-diff (file &optional switches) @@ -757,28 +867,19 @@ dired-do-shell-command (dired-read-shell-command "! on %s: " current-prefix-arg files) current-prefix-arg files))) - (cl-flet ((need-confirm-p - (cmd str) - (let ((res cmd) - (regexp (regexp-quote str))) - ;; Drop all ? and * surrounded by spaces and `?`. - (while (and (string-match regexp res) - (dired--star-or-qmark-p res str)) - (setq res (replace-match "" t t res 2))) - (string-match regexp res)))) (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) + (confirmations nil) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. - (ok (cond ((not (or on-each no-subst)) - (error "You can not combine `*' and `?' substitution marks")) - ((need-confirm-p command "*") - (y-or-n-p (format-message - "Confirm--do you mean to use `*' as a wildcard? "))) - ((need-confirm-p command "?") - (y-or-n-p (format-message - "Confirm--do you mean to use `?' as a wildcard? "))) - (t)))) + (ok (cond + ((not (or on-each no-subst)) + (error "You can not combine `*' and `?' substitution marks")) + ((setq confirmations (dired--need-confirm-positions command "*")) + (dired--no-subst-confirm confirmations command)) + ((setq confirmations (dired--need-confirm-positions command "?")) + (dired--no-subst-confirm confirmations command)) + (t)))) (cond ((not ok) (message "Command canceled")) (t (if on-each @@ -789,7 +890,7 @@ dired-do-shell-command nil file-list) ;; execute the shell command (dired-run-shell-command - (dired-shell-stuff-it command file-list nil arg)))))))) + (dired-shell-stuff-it command file-list nil arg))))))) ;; Might use {,} for bash or csh: (defvar dired-mark-prefix "" diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ccd3192792..e1d9eefbea 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -28,7 +28,7 @@ dired-test-bug27496 (let* ((foo (make-temp-file "foo")) (files (list foo))) (unwind-protect - (cl-letf (((symbol-function 'y-or-n-p) 'error)) + (cl-letf (((symbol-function 'read-multiple-choice) 'error)) (dired temporary-file-directory) (dired-goto-file foo) ;; `dired-do-shell-command' returns nil on success. @@ -114,6 +114,49 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(defun dired-test--check-highlighting (command positions) + (let ((start 1)) + (dolist (pos positions) + (should-not (text-property-not-all start (1- pos) 'face nil command)) + (should (equal 'warning (get-text-property pos 'face command))) + (setq start (1+ pos))) + (should-not (text-property-not-all + start (length command) 'face nil command)))) + +(ert-deftest dired-test-highlight-metachar () + "Check that non-isolated meta-characters are highlighted." + (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (markers " ^ ^") + (result (dired--highlight-no-subst-chars + (dired--need-confirm-positions command "?") + command + t)) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(15 29))) + ;; Note that `?` is considered isolated, but `*` is not. + (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (markers " ^ ^") + (result (dired--highlight-no-subst-chars + (dired--need-confirm-positions command "*") + command + t)) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(11 25))) + (let* ((command "sed 's/\\?/!/'") + (result (dired--highlight-no-subst-chars + (dired--need-confirm-positions command "?") + command + nil)) + (lines (split-string result "\n"))) + (should (= (length lines) 1)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (dired-test--check-highlighting (nth 0 lines) '(8)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.24.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Tweak-dired-warning-about-wildcard-characters-rcfm-squashed.patch >From 2b6d4fda6bbe2cae2d77d099f65c77bdb5ebc161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 18 Dec 2019 07:54:01 +0100 Subject: [PATCH] Tweak dired warning about "wildcard" characters Non-isolated '?' and '*' characters may be quoted, or backslash-escaped; we do not know for a fact that the shell will interpret them as wildcards. Rephrase the prompt and offer to highlight the characters so that the user sees exactly what we are talking about. * lisp/dired-aux.el (dired-isolated-string-re): Use explicitly numbered groups. (dired--star-or-qmark-p): Add START parameter. Make sure to return the first isolated match. (dired--need-confirm-positions, dired--mark-positions) (dired--highlight-no-subst-chars, dired--no-subst-explain) (dired--no-subst-ask, dired--no-subst-confirm): New functions. (dired-do-shell-command): Use them. * test/lisp/dired-aux-tests.el (dired-test-bug27496): Adapt to new prompt. (dired-test--check-highlighting): New test helper. (dired-test-highlight-metachar): New tests. Co-authored-by: Noam Postavsky (bug#28969, bug#35564) --- lisp/dired-aux.el | 151 +++++++++++++++++++++++++++++------ test/lisp/dired-aux-tests.el | 45 ++++++++++- 2 files changed, 169 insertions(+), 27 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index fb1ad6266d..20b056e9f1 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -60,24 +60,132 @@ dired-isolated-string-re of a string followed/prefixed with an space. The regexp capture the preceding blank, STRING and the following blank as the groups 1, 2 and 3 respectively." - (format "\\(\\`\\|[ \t]\\)\\(%s\\)\\([ \t]\\|\\'\\)" string)) + (format "\\(?1:\\`\\|[ \t]\\)\\(?2:%s\\)\\(?3:[ \t]\\|\\'\\)" string)) -(defun dired--star-or-qmark-p (string match &optional keep) +(defun dired--star-or-qmark-p (string match &optional keep start) "Return non-nil if STRING contains isolated MATCH or `\\=`?\\=`'. MATCH should be the strings \"?\", `\\=`?\\=`', \"*\" or nil. The latter means STRING contains either \"?\" or `\\=`?\\=`' or \"*\". If optional arg KEEP is non-nil, then preserve the match data. Otherwise, this function changes it and saves MATCH as the second match group. +START is the position to start matching from. Isolated means that MATCH is surrounded by spaces or at the beginning/end of STRING followed/prefixed with an space. A match to `\\=`?\\=`', isolated or not, is also valid." - (let ((regexps (list (dired-isolated-string-re (if match (regexp-quote match) "[*?]"))))) + (let ((regexp (dired-isolated-string-re (if match (regexp-quote match) "[*?]")))) (when (or (null match) (equal match "?")) - (setq regexps (append (list "\\(\\)\\(`\\?`\\)\\(\\)") regexps))) - (cl-some (lambda (x) - (funcall (if keep #'string-match-p #'string-match) x string)) - regexps))) + (cl-callf concat regexp "\\|\\(?1:\\)\\(?2:`\\?`\\)\\(?3:\\)")) + (funcall (if keep #'string-match-p #'string-match) regexp string start))) + +(defun dired--need-confirm-positions (command string) + "Search for non-isolated matches of STRING in COMMAND. +Return a list of positions that match STRING, but would not be +considered \"isolated\" by `dired--star-or-qmark-p'." + (cl-assert (= (length string) 1)) + (let ((start 0) + (isolated-char-positions nil) + (confirm-positions nil) + (regexp (regexp-quote string))) + ;; Collect all ? and * surrounded by spaces and `?`. + (while (dired--star-or-qmark-p command string nil start) + (push (cons (match-beginning 2) (match-end 2)) + isolated-char-positions) + (setq start (match-end 2))) + ;; Now collect any remaining ? and *. + (setq start 0) + (while (string-match regexp command start) + (unless (cl-member (match-beginning 0) isolated-char-positions + :test (lambda (pos match) + (<= (car match) pos (cdr match)))) + (push (match-beginning 0) confirm-positions)) + (setq start (match-end 0))) + confirm-positions)) + +(defun dired--mark-positions (positions) + (let ((markers (make-string + (1+ (apply #'max positions)) + ?\s))) + (dolist (pos positions) + (setf (aref markers pos) ?^)) + markers)) + +(defun dired--highlight-no-subst-chars (positions command mark) + (cl-callf substring-no-properties command) + (dolist (pos positions) + (add-face-text-property pos (1+ pos) 'warning nil command)) + (if mark + (concat command "\n" (dired--mark-positions positions)) + command)) + +(defun dired--no-subst-explain (buf char-positions command mark-positions) + (with-current-buffer buf + (erase-buffer) + (insert + (format-message "\ +If your command contains occurrences of `*' surrounded by +whitespace, `dired-do-shell-command' substitutes them for the +entire file list to process. Otherwise, if your command contains +occurrences of `?' surrounded by whitespace or `%s', Dired will +run the command once for each file, substituting `?' for each +file name. + +Your command contains occurrences of `%s' that will not be +substituted, and will be passed through normally to the shell. + +%s + +(Press ^ to %s markers below these occurrences.) +" + "`" + (string (aref command (car char-positions))) + (dired--highlight-no-subst-chars char-positions command mark-positions) + (if mark-positions "remove" "add"))))) + +(defun dired--no-subst-ask (char nb-occur details) + (let ((hilit-char (propertize (string char) 'face 'warning)) + (choices `(?y ?n ?? ,@(when details '(?^))))) + (read-char-from-minibuffer + (format-message + (ngettext + "%d occurrence of `%s' will not be substituted. Proceed? (%s) " + "%d occurrences of `%s' will not be substituted. Proceed? (%s) " + nb-occur) + nb-occur hilit-char (mapconcat #'string choices ", ")) + choices))) + +(defun dired--no-subst-confirm (char-positions command) + (let ((help-buf (get-buffer-create "*Dired help*")) + (char (aref command (car char-positions))) + (nb-occur (length char-positions)) + (done nil) + (details nil) + (markers nil) + proceed) + (unwind-protect + (save-window-excursion + (while (not done) + (cl-case (dired--no-subst-ask char nb-occur details) + (?y + (setq done t + proceed t)) + (?n + (setq done t + proceed nil)) + (?? + (if details + (progn + (quit-window nil details) + (setq details nil)) + (dired--no-subst-explain + help-buf char-positions command markers) + (setq details (display-buffer help-buf)))) + (?^ + (setq markers (not markers)) + (dired--no-subst-explain + help-buf char-positions command markers))))) + (kill-buffer help-buf)) + proceed)) ;;;###autoload (defun dired-diff (file &optional switches) @@ -757,28 +865,19 @@ dired-do-shell-command (dired-read-shell-command "! on %s: " current-prefix-arg files) current-prefix-arg files))) - (cl-flet ((need-confirm-p - (cmd str) - (let ((res cmd) - (regexp (regexp-quote str))) - ;; Drop all ? and * surrounded by spaces and `?`. - (while (and (string-match regexp res) - (dired--star-or-qmark-p res str)) - (setq res (replace-match "" t t res 2))) - (string-match regexp res)))) (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) + (confirmations nil) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. - (ok (cond ((not (or on-each no-subst)) - (error "You can not combine `*' and `?' substitution marks")) - ((need-confirm-p command "*") - (y-or-n-p (format-message - "Confirm--do you mean to use `*' as a wildcard? "))) - ((need-confirm-p command "?") - (y-or-n-p (format-message - "Confirm--do you mean to use `?' as a wildcard? "))) - (t)))) + (ok (cond + ((not (or on-each no-subst)) + (error "You can not combine `*' and `?' substitution marks")) + ((setq confirmations (dired--need-confirm-positions command "*")) + (dired--no-subst-confirm confirmations command)) + ((setq confirmations (dired--need-confirm-positions command "?")) + (dired--no-subst-confirm confirmations command)) + (t)))) (cond ((not ok) (message "Command canceled")) (t (if on-each @@ -789,7 +888,7 @@ dired-do-shell-command nil file-list) ;; execute the shell command (dired-run-shell-command - (dired-shell-stuff-it command file-list nil arg)))))))) + (dired-shell-stuff-it command file-list nil arg))))))) ;; Might use {,} for bash or csh: (defvar dired-mark-prefix "" diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index ccd3192792..64a8a035da 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -28,7 +28,7 @@ dired-test-bug27496 (let* ((foo (make-temp-file "foo")) (files (list foo))) (unwind-protect - (cl-letf (((symbol-function 'y-or-n-p) 'error)) + (cl-letf (((symbol-function 'read-char-from-minibuffer) 'error)) (dired temporary-file-directory) (dired-goto-file foo) ;; `dired-do-shell-command' returns nil on success. @@ -114,6 +114,49 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(defun dired-test--check-highlighting (command positions) + (let ((start 1)) + (dolist (pos positions) + (should-not (text-property-not-all start (1- pos) 'face nil command)) + (should (equal 'warning (get-text-property pos 'face command))) + (setq start (1+ pos))) + (should-not (text-property-not-all + start (length command) 'face nil command)))) + +(ert-deftest dired-test-highlight-metachar () + "Check that non-isolated meta-characters are highlighted." + (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (markers " ^ ^") + (result (dired--highlight-no-subst-chars + (dired--need-confirm-positions command "?") + command + t)) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(15 29))) + ;; Note that `?` is considered isolated, but `*` is not. + (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (markers " ^ ^") + (result (dired--highlight-no-subst-chars + (dired--need-confirm-positions command "*") + command + t)) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(11 25))) + (let* ((command "sed 's/\\?/!/'") + (result (dired--highlight-no-subst-chars + (dired--need-confirm-positions command "?") + command + nil)) + (lines (split-string result "\n"))) + (should (= (length lines) 1)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (dired-test--check-highlighting (nth 0 lines) '(8)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.24.0 --=-=-= Content-Type: text/plain For reference, here is the diff between both the read-multiple-choice and the read-char-from-minibuffer options: --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=rmc-vs-rcfm.patch diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 564c6931b5..20b056e9f1 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -134,27 +134,25 @@ dired--no-subst-explain substituted, and will be passed through normally to the shell. %s + +(Press ^ to %s markers below these occurrences.) " "`" (string (aref command (car char-positions))) - (dired--highlight-no-subst-chars char-positions command mark-positions))))) + (dired--highlight-no-subst-chars char-positions command mark-positions) + (if mark-positions "remove" "add"))))) (defun dired--no-subst-ask (char nb-occur details) - (let ((hilit-char (propertize (string char) 'face 'warning))) - (car - (read-multiple-choice - (format-message - (ngettext - "%d occurrence of `%s' will not be substituted. Proceed?" - "%d occurrences of `%s' will not be substituted. Proceed?" - nb-occur) - nb-occur hilit-char) - `((?y "yes" "Send shell command without substituting.") - (?n "no" "Abort.") - (?d "toggle details" ,(format-message - "Show/hide occurrences of `%s'." hilit-char)) - ,@(when details - '((?m "toggle markers" "Show/hide `^' markers.")))))))) + (let ((hilit-char (propertize (string char) 'face 'warning)) + (choices `(?y ?n ?? ,@(when details '(?^))))) + (read-char-from-minibuffer + (format-message + (ngettext + "%d occurrence of `%s' will not be substituted. Proceed? (%s) " + "%d occurrences of `%s' will not be substituted. Proceed? (%s) " + nb-occur) + nb-occur hilit-char (mapconcat #'string choices ", ")) + choices))) (defun dired--no-subst-confirm (char-positions command) (let ((help-buf (get-buffer-create "*Dired help*")) @@ -174,7 +172,7 @@ dired--no-subst-confirm (?n (setq done t proceed nil)) - (?d + (?? (if details (progn (quit-window nil details) @@ -182,7 +180,7 @@ dired--no-subst-confirm (dired--no-subst-explain help-buf char-positions command markers) (setq details (display-buffer help-buf)))) - (?m + (?^ (setq markers (not markers)) (dired--no-subst-explain help-buf char-positions command markers))))) diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index e1d9eefbea..64a8a035da 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -28,7 +28,7 @@ dired-test-bug27496 (let* ((foo (make-temp-file "foo")) (files (list foo))) (unwind-protect - (cl-letf (((symbol-function 'read-multiple-choice) 'error)) + (cl-letf (((symbol-function 'read-char-from-minibuffer) 'error)) (dired temporary-file-directory) (dired-goto-file foo) ;; `dired-do-shell-command' returns nil on success. --=-=-= Content-Type: text/plain Once applied, the patches can be tried out by - opening a Dired buffer, - hitting '!', - inputting e.g. "sed 's/?/!/'". WDYT? Thank you for your time. [1] bug#35564#5 [2] bug#35564#38 [3] bug#35564#62 [4] bug#35564#101 [5] bug#35564#157 [6] bug#35564#187 --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Thu Dec 19 17:20:49 2019 Received: (at 35564) by debbugs.gnu.org; 19 Dec 2019 22:20:49 +0000 Received: from localhost ([127.0.0.1]:45653 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ii4A5-0005k2-C8 for submit@debbugs.gnu.org; Thu, 19 Dec 2019 17:20:49 -0500 Received: from dog.birch.relay.mailchannels.net ([23.83.209.48]:36116) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ii4A3-0005jm-1w for 35564@debbugs.gnu.org; Thu, 19 Dec 2019 17:20:48 -0500 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 5B40A341D4E; Thu, 19 Dec 2019 22:20:45 +0000 (UTC) Received: from pdx1-sub0-mail-a58.g.dreamhost.com (100-96-196-19.trex.outbound.svc.cluster.local [100.96.196.19]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 209E3341C84; Thu, 19 Dec 2019 22:20:41 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from pdx1-sub0-mail-a58.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.18.5); Thu, 19 Dec 2019 22:20:45 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Eyes-Sponge: 1607482e03367f04_1576794041471_1672107611 X-MC-Loop-Signature: 1576794041471:1979795016 X-MC-Ingress-Time: 1576794041471 Received: from pdx1-sub0-mail-a58.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a58.g.dreamhost.com (Postfix) with ESMTP id DBB1F8061A; Thu, 19 Dec 2019 14:20:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=linkov.net; bh=X3OCkNr1rs9+53raZOTYXHDJuME=; b= qkEX8RmuYWEGz54UOL4ZQ3Z/Ix890bGKTy5qdxkmgiTHDrJ3gWQcs4C1TLnWFFuj k/Fui6EivbY/LBeL5RK5H4QITq6G2rReqjhUMNgXzdx5JPabirXF4nlUZvJnc0LY Vv6P/kWyjopr5g48HTRv8bbYBUIYm0x01Lv6LMKexE8= Received: from mail.jurta.org (m91-129-107-186.cust.tele2.ee [91.129.107.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a58.g.dreamhost.com (Postfix) with ESMTPSA id 99F6B80609; Thu, 19 Dec 2019 14:20:32 -0800 (PST) X-DH-BACKEND: pdx1-sub0-mail-a58 From: Juri Linkov To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters Organization: LINKOV.NET References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87a77qhzvm.fsf@gmail.com> Date: Fri, 20 Dec 2019 00:01:03 +0200 In-Reply-To: <87a77qhzvm.fsf@gmail.com> (=?iso-8859-1?Q?=22K=E9vin?= Le Gouguec"'s message of "Wed, 18 Dec 2019 08:11:25 +0100") Message-ID: <87v9qcf00w.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain X-VR-OUT-STATUS: OK X-VR-OUT-SCORE: -100 X-VR-OUT-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedufedrvdduuddgudehlecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucggtfgfnhhsuhgsshgtrhhisggvpdfftffgtefojffquffvnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvffuohhfffgjkfgfgggtsehttdertddtredtnecuhfhrohhmpefluhhrihcunfhinhhkohhvuceojhhurhhisehlihhnkhhovhdrnhgvtheqnecukfhppeeluddruddvledruddtjedrudekieenucfrrghrrghmpehmohguvgepshhmthhppdhhvghlohepmhgrihhlrdhjuhhrthgrrdhorhhgpdhinhgvthepledurdduvdelrddutdejrddukeeipdhrvghtuhhrnhdqphgrthhhpefluhhrihcunfhinhhkohhvuceojhhurhhisehlihhnkhhovhdrnhgvtheqpdhmrghilhhfrhhomhepjhhurhhisehlihhnkhhovhdrnhgvthdpnhhrtghpthhtohepkhgvvhhinhdrlhgvghhouhhguhgvtgesghhmrghilhdrtghomhenucevlhhushhtvghrufhiiigvpedt X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier , Eli Zaretskii , Drew Adams X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > Once applied, the patches can be tried out by > > - opening a Dired buffer, > - hitting '!', > - inputting e.g. "sed 's/?/!/'". > > WDYT? Thanks. I tried out your patch with read-char-from-minibuffer and it works smoothly without any problem. Please ask Eli for a permission to push it before starting the pretest. From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 20 03:53:45 2019 Received: (at 35564) by debbugs.gnu.org; 20 Dec 2019 08:53:45 +0000 Received: from localhost ([127.0.0.1]:45903 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iiE2b-0004Va-As for submit@debbugs.gnu.org; Fri, 20 Dec 2019 03:53:45 -0500 Received: from eggs.gnu.org ([209.51.188.92]:53583) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iiE2Z-0004VM-Eo for 35564@debbugs.gnu.org; Fri, 20 Dec 2019 03:53:43 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]:48391) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iiE2S-0003R7-Sp; Fri, 20 Dec 2019 03:53:37 -0500 Received: from [176.228.60.248] (port=1936 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1iiE2S-00015z-BK; Fri, 20 Dec 2019 03:53:36 -0500 Date: Fri, 20 Dec 2019 10:53:30 +0200 Message-Id: <837e2r1iph.fsf@gnu.org> From: Eli Zaretskii To: Juri Linkov In-reply-to: <87v9qcf00w.fsf@mail.linkov.net> (message from Juri Linkov on Fri, 20 Dec 2019 00:01:03 +0200) Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87a77qhzvm.fsf@gmail.com> <87v9qcf00w.fsf@mail.linkov.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 35564 Cc: michael_heerdegen@web.de, 35564@debbugs.gnu.org, npostavs@gmail.com, monnier@iro.umontreal.ca, kevin.legouguec@gmail.com, drew.adams@oracle.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > From: Juri Linkov > Cc: 35564@debbugs.gnu.org, Michael Heerdegen , > Noam Postavsky , Stefan Monnier > , Eli Zaretskii , Drew Adams > > Date: Fri, 20 Dec 2019 00:01:03 +0200 > > > Once applied, the patches can be tried out by > > > > - opening a Dired buffer, > > - hitting '!', > > - inputting e.g. "sed 's/?/!/'". > > > > WDYT? > > Thanks. I tried out your patch with read-char-from-minibuffer > and it works smoothly without any problem. Please ask Eli > for a permission to push it before starting the pretest. I'll let other participants of this long discussion to chime in, but in general I'd like to postpone this till after the emacs-27 branch is cut (hopefully, very soon), as this constitutes a significant behavior change, AFAIU. Thanks. From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 20 15:34:18 2019 Received: (at 35564) by debbugs.gnu.org; 20 Dec 2019 20:34:18 +0000 Received: from localhost ([127.0.0.1]:47284 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iiOyX-0007ib-VM for submit@debbugs.gnu.org; Fri, 20 Dec 2019 15:34:18 -0500 Received: from mail-wr1-f47.google.com ([209.85.221.47]:37740) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iiOyV-0007iN-HJ for 35564@debbugs.gnu.org; Fri, 20 Dec 2019 15:34:16 -0500 Received: by mail-wr1-f47.google.com with SMTP id w15so10664515wru.4 for <35564@debbugs.gnu.org>; Fri, 20 Dec 2019 12:34:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=T9afDy9KYFU1Wbni5RbxZP6WXGA02fPS8Mtfdr0d3+Y=; b=IludgO9zb4OjZk+a0CnoCIUhUV9a+GpdAzHtSzdNdPHCQ/PRkYC6f4sqwtNtdqj1Rb fXe/D+jjcpo/5uXpwOyb152wPdcHUL2oDhZ3hx+Iy3ZvDCpTHRymKrguvmlbGE2Mxq1p U9ld/qRnSbe9358gdR2YUgdT9URHmI7kHssrqm7b9tdsx49ULfz0OdrRHHIksib965n0 a7IlsLED3wNoMwXLplkpiqeG6ltipfmRxqChC/AsA/1RULloDv8/X7MJYdSGn2WvSXj/ WsmEcPDDpsX9VNb0GyTqq3BxLbYm/+DDhj829Xxwc9Ejm77QZWUN2w21mxmGrQtBG5iH OoFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=T9afDy9KYFU1Wbni5RbxZP6WXGA02fPS8Mtfdr0d3+Y=; b=r9GerflX4+DaTpNhTyKW9XYq/7q8m2s2gsxuIli+5iodZ05gX16OwGvUPodpgTVtux gIKKi6/ga6SRysezK1nFozWKnvYr3o/ntwNN7jLWIpZvUd0sA82aZ3cpsbc9RmzWXqJN QawRNBMovbJqt379zUnyvz4yltCxiw9MjZkLx2Rl1C2Md01IDvI8p+wTZUdC3FlErfXX mqSZVceLq+5ifcVV6cvq8FykiId9PuY0N+zxkWF4fnCBE4l+dNNCi6FVlEfQBLjY+eGY JmM60kZV/OO0cUXuyoQxljNs9olkpQTtd+zofMHSwoP7eYqe/hGeC/WHobQLrw+9BZ7H bA3w== X-Gm-Message-State: APjAAAU0pIPQiHce0O+JlXUsUNIk51pEOFHl/hhp9vDWyKotqqg6O0qT 04yW23kcYJ3Iztd/OGPRAHk= X-Google-Smtp-Source: APXvYqyyaBCG0vARV4dqbnUxh4+KKrNbSMZL3F3NN2FjAYwOQc00Y9gQRq9hBucpKYW5NAKOyCgMDA== X-Received: by 2002:adf:f10a:: with SMTP id r10mr17018572wro.202.1576874049687; Fri, 20 Dec 2019 12:34:09 -0800 (PST) Received: from my-little-tumbleweed (200.143.13.109.rev.sfr.net. [109.13.143.200]) by smtp.gmail.com with ESMTPSA id z187sm11071128wme.16.2019.12.20.12.34.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Dec 2019 12:34:08 -0800 (PST) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Eli Zaretskii Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87a77qhzvm.fsf@gmail.com> <87v9qcf00w.fsf@mail.linkov.net> <837e2r1iph.fsf@gnu.org> Date: Fri, 20 Dec 2019 21:34:07 +0100 In-Reply-To: <837e2r1iph.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 20 Dec 2019 10:53:30 +0200") Message-ID: <87a77mn3cw.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: michael_heerdegen@web.de, 35564@debbugs.gnu.org, npostavs@gmail.com, Juri Linkov , monnier@iro.umontreal.ca, drew.adams@oracle.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Eli Zaretskii writes: > I'll let other participants of this long discussion to chime in, but > in general I'd like to postpone this till after the emacs-27 branch is > cut (hopefully, very soon), as this constitutes a significant behavior > change, AFAIU. I won't insist too much for this to land on Emacs 27, since a) the "bug" it fixes is fairly minor, b) I know everyone's plate is quite full, and c) I mostly use the master branch anyway, so it's not like I'll have to wait to benefit. For the record though, I'll point out a few reasons why I think it should be "safe" to include this in the upcoming release: - the changes are fairly limited in scope: they only affect dired-do-shell-command; - in the simplest case, the UI change is minor: it turns this message: > Confirm--do you mean to use =E2=80=98?=E2=80=99 as a wildcard? (y or n) into this one: > 1 occurrence of =E2=80=98?=E2=80=99 will not be substituted. Proceed? = (y, n, ?) ? (or, with read-multiple-choice:) > 1 occurrence of =E2=80=98?=E2=80=99 will not be substituted. Proceed? = (_y_es, _n_o, toggle _d_etails, _?_):=20 - the "riskiest" refactoring changes have been handled by Noam[1] and are partially covered by unit tests. Most of the lengthy discussion was about finding the right balance between message correctness and verbosity; hopefully the eventual behavior change is not that significant. > Thanks. Thank you for your time. [1] https://debbugs.gnu.org/cgi/bugreport.cgi?att=3D2;filename=3D0002-Dedup= -dired-aux-isolated-char-searching-Bug-35564.patch;bug=3D35564;msg=3D202 From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 20 15:44:09 2019 Received: (at 35564) by debbugs.gnu.org; 20 Dec 2019 20:44:09 +0000 Received: from localhost ([127.0.0.1]:47288 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iiP84-0007w8-VY for submit@debbugs.gnu.org; Fri, 20 Dec 2019 15:44:09 -0500 Received: from mail-wm1-f54.google.com ([209.85.128.54]:37277) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iiP82-0007vX-1q for 35564@debbugs.gnu.org; Fri, 20 Dec 2019 15:44:08 -0500 Received: by mail-wm1-f54.google.com with SMTP id f129so10529052wmf.2 for <35564@debbugs.gnu.org>; Fri, 20 Dec 2019 12:44:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=Zh12gV0rDLg0qHe6axLJhIPqPgYWj9AH+hDvPkMo4jM=; b=M06u8+JZl+RZ1VOF2ZiSBcBtg3xPmNpxl82j9eYoOJUI1Ypqo14kNlI2C1t8kc0KSu PAN+4uYcTnmf/p40i9CbFo4f5PdJJ1w/5extt0XnrzcP1P9F3ukXmJcRA07SzwB1aR5L ffOJPkj6tCRLHqW6adDOumCZepbCBZWE1Of2oJ+W4bz/eqT9jb2fB+TbjWjqdggHS42/ 5UKLucwsYosavE4sGLaqFddZCSjeRZNCy5flmM3XVgHdV+A2HF5+eP/tBtOxQJjhP5Tw x75ayxDn2fEA8/8jUA3GglCh2sQBIIPNM0WJK1jZD1rCpUUGsoeNZEqjXXHE0EYNRCMi L2ww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=Zh12gV0rDLg0qHe6axLJhIPqPgYWj9AH+hDvPkMo4jM=; b=n2kGkrF3AYGrYOGi/ZFaycyvEBSs4mcxGomEuub5c2a3ydAqJZYzG2mTyDVBVOVKf4 nfoLkCFNxdLnF2bfV/bxVNzadHaJFHR/Ki+dh7ZTY1z3w0gQdxbYKuEHZRQImiwa3nFc qri4uMhWOBeBlSbqQudDz+kw//hMrzzRvHjbBbjkRQ+CjU4VUVbGuhcYQw1ysLpIh3jd 6dH1PTH/uBQLuUcYD4AOtakLIQgAQ3j6BRCFV+AP7dfu+GoU0PMRd70Rdr6b1p0ChzGq egX351EwPYiDNVF5SdWWxlkc0wbRft0a3ug2yJFHgJ1mH/bzBQZgsGA3TzczjE/IBOOY bmGA== X-Gm-Message-State: APjAAAWUAtDWaT2zP9QzBULpmKTURU8WuXZNGGZY8er4COQI5h4HUTIl 1osmnlismamBJPD5aJqwPhc= X-Google-Smtp-Source: APXvYqzZVVtp4FoeFHrjzr0o1B7vzWUy0vt+ccMQlNPDeLkqw/F230zum1E8IofL+LHkrIjLQondLA== X-Received: by 2002:a7b:c750:: with SMTP id w16mr19470235wmk.46.1576874640242; Fri, 20 Dec 2019 12:44:00 -0800 (PST) Received: from my-little-tumbleweed (200.143.13.109.rev.sfr.net. [109.13.143.200]) by smtp.gmail.com with ESMTPSA id z83sm11239594wmg.2.2019.12.20.12.43.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Dec 2019 12:43:59 -0800 (PST) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Juri Linkov Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87a77qhzvm.fsf@gmail.com> <87v9qcf00w.fsf@mail.linkov.net> Date: Fri, 20 Dec 2019 21:43:59 +0100 In-Reply-To: <87v9qcf00w.fsf@mail.linkov.net> (Juri Linkov's message of "Fri, 20 Dec 2019 00:01:03 +0200") Message-ID: <875zian2wg.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: Michael Heerdegen , 35564@debbugs.gnu.org, Noam Postavsky , Stefan Monnier , Eli Zaretskii , Drew Adams X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Juri Linkov writes: > Thanks. I tried out your patch with read-char-from-minibuffer > and it works smoothly without any problem. Please ask Eli > for a permission to push it before starting the pretest. Glad to hear it! Like Eli, I'd like to collect some feedback, e.g. from Michael who submitted bug#28969 and suggested read-multiple-choice. Some additional remarks: - I do not have push access AFAIK, so feel free to install whenever you think there is consensus on whether to wait for emacs-27 to fork off. - I guess there is also the question of whether to push the five patches or the squashed one (all have valid commit messages, unless I messed up). From debbugs-submit-bounces@debbugs.gnu.org Sat Dec 21 02:08:24 2019 Received: (at 35564) by debbugs.gnu.org; 21 Dec 2019 07:08:24 +0000 Received: from localhost ([127.0.0.1]:47566 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iiYsB-00062L-OV for submit@debbugs.gnu.org; Sat, 21 Dec 2019 02:08:23 -0500 Received: from eggs.gnu.org ([209.51.188.92]:37990) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iiYsA-00062A-OP for 35564@debbugs.gnu.org; Sat, 21 Dec 2019 02:08:23 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]:55119) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iiYs4-0006bm-Hl; Sat, 21 Dec 2019 02:08:16 -0500 Received: from [176.228.60.248] (port=4620 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1iiYs3-0005eA-W8; Sat, 21 Dec 2019 02:08:16 -0500 Date: Sat, 21 Dec 2019 09:08:05 +0200 Message-Id: <834kxu17hm.fsf@gnu.org> From: Eli Zaretskii To: =?utf-8?Q?K=C3=A9vin?= Le Gouguec In-reply-to: <87a77mn3cw.fsf@gmail.com> (message from =?utf-8?Q?K=C3=A9vin?= Le Gouguec on Fri, 20 Dec 2019 21:34:07 +0100) Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87a77qhzvm.fsf@gmail.com> <87v9qcf00w.fsf@mail.linkov.net> <837e2r1iph.fsf@gnu.org> <87a77mn3cw.fsf@gmail.com> MIME-version: 1.0 Content-type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 35564 Cc: michael_heerdegen@web.de, 35564@debbugs.gnu.org, npostavs@gmail.com, juri@linkov.net, monnier@iro.umontreal.ca, drew.adams@oracle.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > From: Kévin Le Gouguec > Cc: Juri Linkov , 35564@debbugs.gnu.org, > michael_heerdegen@web.de, npostavs@gmail.com, monnier@iro.umontreal.ca, > drew.adams@oracle.com > Date: Fri, 20 Dec 2019 21:34:07 +0100 > > - in the simplest case, the UI change is minor: it turns this message: > > > Confirm--do you mean to use ‘?’ as a wildcard? (y or n) > > into this one: > > > 1 occurrence of ‘?’ will not be substituted. Proceed? (y, n, ?) ? > > (or, with read-multiple-choice:) > > > 1 occurrence of ‘?’ will not be substituted. Proceed? (_y_es, _n_o, toggle _d_etails, _?_): Is this the best wording you've been able to arrive at? It sounds slightly confusing to me (but then I don't use this facility too much). The confusing part is that it talks about "substitution", and the user might not be aware that there is any substitution going on. Thanks. From debbugs-submit-bounces@debbugs.gnu.org Sat Dec 21 02:08:52 2019 Received: (at 35564) by debbugs.gnu.org; 21 Dec 2019 07:08:52 +0000 Received: from localhost ([127.0.0.1]:47569 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iiYse-000630-1U for submit@debbugs.gnu.org; Sat, 21 Dec 2019 02:08:52 -0500 Received: from eggs.gnu.org ([209.51.188.92]:41201) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iiYsc-00062m-JR for 35564@debbugs.gnu.org; Sat, 21 Dec 2019 02:08:50 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]:55123) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iiYsX-00004u-CW; Sat, 21 Dec 2019 02:08:45 -0500 Received: from [176.228.60.248] (port=4653 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1iiYsW-0005eM-NJ; Sat, 21 Dec 2019 02:08:45 -0500 Date: Sat, 21 Dec 2019 09:08:36 +0200 Message-Id: <8336de17gr.fsf@gnu.org> From: Eli Zaretskii To: =?iso-8859-1?Q?K=E9vin?= Le Gouguec In-reply-to: <875zian2wg.fsf@gmail.com> (message from =?iso-8859-1?Q?K=E9v?= =?iso-8859-1?Q?in?= Le Gouguec on Fri, 20 Dec 2019 21:43:59 +0100) Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87a77qhzvm.fsf@gmail.com> <87v9qcf00w.fsf@mail.linkov.net> <875zian2wg.fsf@gmail.com> MIME-version: 1.0 Content-type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 35564 Cc: michael_heerdegen@web.de, 35564@debbugs.gnu.org, npostavs@gmail.com, juri@linkov.net, monnier@iro.umontreal.ca, drew.adams@oracle.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > From: Kévin Le Gouguec > Cc: 35564@debbugs.gnu.org, Michael Heerdegen , > Noam Postavsky , Stefan Monnier > , Eli Zaretskii , Drew Adams > > Date: Fri, 20 Dec 2019 21:43:59 +0100 > > - I guess there is also the question of whether to push the five patches > or the squashed one (all have valid commit messages, unless I messed > up). The latter, please. From debbugs-submit-bounces@debbugs.gnu.org Sun Dec 22 11:02:19 2019 Received: (at 35564) by debbugs.gnu.org; 22 Dec 2019 16:02:20 +0000 Received: from localhost ([127.0.0.1]:50155 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ij3gR-0008Ol-Hb for submit@debbugs.gnu.org; Sun, 22 Dec 2019 11:02:19 -0500 Received: from mail-wm1-f45.google.com ([209.85.128.45]:40065) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ij3gQ-0008OY-Hi for 35564@debbugs.gnu.org; Sun, 22 Dec 2019 11:02:19 -0500 Received: by mail-wm1-f45.google.com with SMTP id t14so13825277wmi.5 for <35564@debbugs.gnu.org>; Sun, 22 Dec 2019 08:02:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:message-id:user-agent :mime-version:content-transfer-encoding; bh=YGewpqLeV/3yk1z0OqYPeuor0Kqcv2xj43fTKf0MSeI=; b=Yqd0Dw4AOojijQBhpAWnD9cXYMPSDYdhwnHgRICqkbjvcwRUDnv4WNq1kFJfSDQCO4 DlZXT+5L0aWgEuoOypqBO7eUmpJVu7EnzT6at2GCWtUfo5ktBplbfw55wPS3IA4eMqtf 1lKYJP10gX3zVNVnAcMgHoNQVr3pmjBHxO7tBZNeAafmNG6TpylKy9qtBhc4fEiF0E4T R0TNVeu6qmmLZDk1WWC5bdjZyad2NTvqiNIDfKCZgVLt/rdJFwcn/eA+N32YLy7sZOxb 8VyeLbA6Cefmsr+1AOkfNr6uvJjzwRB6XHrSet8poCRtoKki/DFIS2ry583++dmUHQGr TFfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:message-id :user-agent:mime-version:content-transfer-encoding; bh=YGewpqLeV/3yk1z0OqYPeuor0Kqcv2xj43fTKf0MSeI=; b=R5G0fy1d7Tr6loJpwxk/rwpEDuPcUkJezvxIB7FcjgUeJ2t6fdHXT0Qc4knGTSSHsi TeOC4mRJzCR4WUDvbc3YsL1TieUdwlgRECPbRJapVRU6rKlSV2pTv6PqF6RuHt7blQTG iPTd6tTdnBympN+2xL29GYnDZnxs9GhOVeHBXoiXl+f20LwTFB0kNwIbvPJYzzvcTzJ3 lBQ7Z5VtwhO/Cvh0aPVCumwbBgvbJGDgPSqLYpEiYFZIMjy77lkWOR0cvyWdnfkthiNf fdBrefhEj+qiKeKQV6ElNDZWN6qecKGNN4PsN2SnLvQSkjVZ/6sFKeXusnQlbwMlNxGW Fp6Q== X-Gm-Message-State: APjAAAUAiD264MMoEyJOICaHbnD7yk1LV2BR/+QxxnEl1ZEvGgvDG0MY ZNyGsBtfvve76e8ONI80l8o= X-Google-Smtp-Source: APXvYqzxAPNV+6DZErsK0lvYzdctFchnLnXFGfBCT4isE7TMR+XA/OCCyTc6RPtfanGCn46juiLTDw== X-Received: by 2002:a7b:c30b:: with SMTP id k11mr27514757wmj.36.1577030532316; Sun, 22 Dec 2019 08:02:12 -0800 (PST) Received: from little-buster ([109.190.253.11]) by smtp.gmail.com with ESMTPSA id r6sm17575984wrq.92.2019.12.22.08.02.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Dec 2019 08:02:11 -0800 (PST) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Eli Zaretskii Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87a77qhzvm.fsf@gmail.com> <87v9qcf00w.fsf@mail.linkov.net> <837e2r1iph.fsf@gnu.org> <87a77mn3cw.fsf@gmail.com> <834kxu17hm.fsf@gnu.org> Date: Sun, 22 Dec 2019 17:02:07 +0100 Message-ID: <87v9q85oxs.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: michael_heerdegen@web.de, 35564@debbugs.gnu.org, npostavs@gmail.com, juri@linkov.net, monnier@iro.umontreal.ca, drew.adams@oracle.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Eli Zaretskii writes: >> From: K=C3=A9vin Le Gouguec >> Cc: Juri Linkov , 35564@debbugs.gnu.org, >> michael_heerdegen@web.de, npostavs@gmail.com, monnier@iro.umontreal.= ca, >> drew.adams@oracle.com >> Date: Fri, 20 Dec 2019 21:34:07 +0100 >>=20 >> - in the simplest case, the UI change is minor: it turns this message: >>=20 >> > Confirm--do you mean to use =E2=80=98?=E2=80=99 as a wildcard? (y or= n) >>=20 >> into this one: >>=20 >> > 1 occurrence of =E2=80=98?=E2=80=99 will not be substituted. Procee= d? (y, n, ?) ? >>=20 >> (or, with read-multiple-choice:) >>=20 >> > 1 occurrence of =E2=80=98?=E2=80=99 will not be substituted. Procee= d? (_y_es, _n_o, toggle _d_etails, _?_):=20 > > Is this the best wording you've been able to arrive at? It sounds > slightly confusing to me (but then I don't use this facility too > much). The confusing part is that it talks about "substitution", and > the user might not be aware that there is any substitution going on. Indeed, that's why the prompt now supports an additional action to pop a help buffer explaining what the deal is[1]. Fundamentally, this prompt *is* about the substitution feature. Dired detects non-isolated occurrences of '*' and '?', and requests confirmation before proceeding without substituting them. With this in mind, explicitly mentioning "substitution" doesn't sound too outlandish=E2= =80=A6 ( Or, we could assume that the current message is correct (i.e. it's the wildcards we want to warn about) but the condition that triggers it is wrong, i.e. Dired should be smarter and only warn when the characters are unquoted and unescaped. That sounds complex to implement though. As Drew noted[2], another way to handle this would be asking users whether they want to substitute the non-isolated characters. That still implies talking about "substitution" though. Also, users can already mark occurrences of '?' for substitution using backquotes, as explained in the new help buffer. ) To wrap up, I'd say that the current message makes me go: "Huh? No, I don't want to use these characters as wildcards." *hits "n", command is aborted* *confusion: extreme & growing* I'm hoping that the new message will have users go: "Huh? Why would Dired substitute these characters?" *hits "?", skims, hits "y", moves on* *confusion: mild & receding* Thank you for your patience, and for reviewing this. [1]=20 > If your command contains occurrences of =E2=80=98*=E2=80=99 surrounded by > whitespace, =E2=80=98dired-do-shell-command=E2=80=99 substitutes them for= the > entire file list to process. Otherwise, if your command contains > occurrences of =E2=80=98?=E2=80=99 surrounded by whitespace or =E2=80=98`= =E2=80=99, Dired will > run the command once for each file, substituting =E2=80=98?=E2=80=99 for = each > file name. >=20 > Your command contains occurrences of =E2=80=98?=E2=80=99 that will not be > substituted, and will be passed through normally to the shell. >=20 > sed 's/?/!/' >=20 > (Press ^ to add markers below these occurrences.) [2] bug#35564#83 From debbugs-submit-bounces@debbugs.gnu.org Sun Sep 20 07:43:05 2020 Received: (at 35564) by debbugs.gnu.org; 20 Sep 2020 11:43:05 +0000 Received: from localhost ([127.0.0.1]:49032 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJxkH-0008N1-8G for submit@debbugs.gnu.org; Sun, 20 Sep 2020 07:43:05 -0400 Received: from quimby.gnus.org ([95.216.78.240]:59860) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJxkF-0008MP-C7 for 35564@debbugs.gnu.org; Sun, 20 Sep 2020 07:43:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Message-ID :In-Reply-To:Date:References:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=+2NCv97zF5IpBRKi22j+TWMnro7tbGI0pJ4LCXFsKSY=; b=srUqspM1p+FLi1hfJl9lYQab2U 3owYviZ5TTd7ZbP9fpAJch2CBRVJWzEE2So6wBHBw5zkwsiqthzDq15MRgo4kA9ryAXI290fFEyoN +Z3W5nJ30TUHoYRCAXQilGplNMDu9m1VIEAB396C5ztGG0Dg/uYGKmeXubitQHgPlDAU=; Received: from cm-84.212.202.86.getinternet.no ([84.212.202.86] helo=xo) by quimby with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kJxjz-00077w-0f; Sun, 20 Sep 2020 13:42:51 +0200 From: Lars Ingebrigtsen To: Eli Zaretskii Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87a77qhzvm.fsf@gmail.com> <87v9qcf00w.fsf@mail.linkov.net> <875zian2wg.fsf@gmail.com> <8336de17gr.fsf@gnu.org> X-Now-Playing: 808 State's _Ninety_: "Cobra Bora" Date: Sun, 20 Sep 2020 13:42:45 +0200 In-Reply-To: <8336de17gr.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 21 Dec 2019 09:08:36 +0200") Message-ID: <87ft7coeru.fsf@gnus.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Report: Spam detection software, running on the system "quimby.gnus.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: Eli Zaretskii writes: >> - I guess there is also the question of whether to push the five patches >> or the squashed one (all have valid commit messages, unless I messed >> up). > > The latter, please. Content analysis details: (-2.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: michael_heerdegen@web.de, 35564@debbugs.gnu.org, npostavs@gmail.com, juri@linkov.net, monnier@iro.umontreal.ca, =?utf-8?Q?K=C3=A9vin?= Le Gouguec , drew.adams@oracle.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Eli Zaretskii writes: >> - I guess there is also the question of whether to push the five patches >> or the squashed one (all have valid commit messages, unless I messed >> up). > > The latter, please. K=C3=A9vin, skimming this thread, there seemed to be a general consensus th= at your patch series should be applied. Could you work up a single squashed patch to apply? There's so many patches with different variations that it's difficult to tell which ones should be applied. --=20 (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no From debbugs-submit-bounces@debbugs.gnu.org Sun Sep 20 07:43:08 2020 Received: (at control) by debbugs.gnu.org; 20 Sep 2020 11:43:08 +0000 Received: from localhost ([127.0.0.1]:49034 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJxkK-0008NB-Il for submit@debbugs.gnu.org; Sun, 20 Sep 2020 07:43:08 -0400 Received: from quimby.gnus.org ([95.216.78.240]:59868) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJxkG-0008MT-QQ for control@debbugs.gnu.org; Sun, 20 Sep 2020 07:43:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Subject:From:To:Message-Id:Date:Sender:Reply-To:Cc: MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=xRx5o56z+r8NuUY4ymclKQUMtOe1x0/yNgx2hM96BnY=; b=NSSJ4WxUe7yDChO8K93rUsZIK0 hZK/nsEeJMOBkenHn/HlQMsKS8Kfi5IaKdC8hO6sxgveJSqCJ/YG8+TkU+KHlk+dgMWy6D8lt1fM6 /IrbtJn3biUD9G2uj8qijF9zJ6Y6m1Uf3+Y2wRufi2nXkFoYXA0vuLnrjVmgTCE4lTBE=; Received: from cm-84.212.202.86.getinternet.no ([84.212.202.86] helo=xo) by quimby with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kJxk9-000787-4K for control@debbugs.gnu.org; Sun, 20 Sep 2020 13:42:59 +0200 Date: Sun, 20 Sep 2020 13:42:55 +0200 Message-Id: <87eemwoerk.fsf@gnus.org> To: control@debbugs.gnu.org From: Lars Ingebrigtsen Subject: control message for bug #35564 X-Spam-Report: Spam detection software, running on the system "quimby.gnus.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: tags 35564 + moreinfo quit Content analysis details: (-2.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) tags 35564 + moreinfo quit From debbugs-submit-bounces@debbugs.gnu.org Sun Sep 20 08:04:56 2020 Received: (at 35564) by debbugs.gnu.org; 20 Sep 2020 12:04:56 +0000 Received: from localhost ([127.0.0.1]:49085 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJy5P-0002cz-FX for submit@debbugs.gnu.org; Sun, 20 Sep 2020 08:04:56 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:34885) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJy5M-0002ci-0B for 35564@debbugs.gnu.org; Sun, 20 Sep 2020 08:04:54 -0400 Received: by mail-wr1-f67.google.com with SMTP id e16so9946859wrm.2 for <35564@debbugs.gnu.org>; Sun, 20 Sep 2020 05:04:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=1FOvW6ZpU8aW+KDDPwQn++1PuFO0/oFLm36JFljcljw=; b=dhFeUL2+GKurYhZeA8VqB8mcrAa5llX8nZv+7vWkWDnIM+9wvbjsfkDnHLvJYJN8Gp cpEJBvWast3MIAHUocZOjq1ZNh+KzmxjEK36Yxazhwmt2p1CWGWooxmwIlkUnIvMyUyJ cCclgAyze6nu7m0QweKCiPVF4tJWzp5OyEFvIQfqDmDyKhQCVPzZ+TqqafnpwpLrw/Rq adVnaChCxdzRaeqlI+Gi/QIfu3NxPLt8V5PdK+fkGC/P4t3kcTqvABA+P1KdLsTRPsXD g/o7M/N046o6E7FXFklqi5fkTlYCTnNT7uSriazkMWGlv2DYFqOVGfrzDLPP8Gwx0+Zy 8jsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=1FOvW6ZpU8aW+KDDPwQn++1PuFO0/oFLm36JFljcljw=; b=Q8o3TTlXNYgCDfjyg6JG1e1G2BTM4ukR83ObNiMhSp4jSm29vaBINmpJahI3h9e6Ch OhFxGVAFRCzvpmjjF2agePyXf1Z89U36+cUwPZ5HMAyJ6DvNWbH+pTj7B9KPjWmilJil vn1PRG2dWAYT/HgT95W5hscsnNRqPKqDqcLqO4FdPBfuU88uWIG6Kjhjx0m6W72Y91sk HgWRY2OdPaHSgtVGM7n0VH92yqezENOZkCtQTvHHWxMvYvRg/t1F4dFwx0Iy7fGG2Po/ NA+FE7exJNzwIQBNkPZ6KDH4PravngdrbDZQ+8mp0XLS/5KfPMcWwqDR2+vDWNpjOKSU X5pQ== X-Gm-Message-State: AOAM532rGO9iWpJSmZIOYGX73OUE2VjbHpZ+8dON/1Uh5EiGYyZ+YMk6 k6T3D5reVi4l0n32VcaP97c= X-Google-Smtp-Source: ABdhPJx4imdIks+AEm7SCZSPfG4TSIGz7skBCvkssJ/t/szFljvRCIIsbgT/9RsxXZNjA4dqhjkouw== X-Received: by 2002:a5d:67d2:: with SMTP id n18mr47188892wrw.223.1600603486215; Sun, 20 Sep 2020 05:04:46 -0700 (PDT) Received: from hirondell (2a01cb040b29800015848624b4c61618.ipv6.abo.wanadoo.fr. [2a01:cb04:b29:8000:1584:8624:b4c6:1618]) by smtp.gmail.com with ESMTPSA id c14sm14639427wrv.12.2020.09.20.05.04.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 20 Sep 2020 05:04:45 -0700 (PDT) From: =?utf-8?Q?K=C3=A9vin_Le_Gouguec?= To: Lars Ingebrigtsen Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87a77qhzvm.fsf@gmail.com> <87v9qcf00w.fsf@mail.linkov.net> <875zian2wg.fsf@gmail.com> <8336de17gr.fsf@gnu.org> <87ft7coeru.fsf@gnus.org> Date: Sun, 20 Sep 2020 14:04:44 +0200 In-Reply-To: <87ft7coeru.fsf@gnus.org> (Lars Ingebrigtsen's message of "Sun, 20 Sep 2020 13:42:45 +0200") Message-ID: <87o8m04psz.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: michael_heerdegen@web.de, 35564@debbugs.gnu.org, npostavs@gmail.com, juri@linkov.net, monnier@iro.umontreal.ca, Eli Zaretskii , drew.adams@oracle.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Lars Ingebrigtsen writes: > K=C3=A9vin, skimming this thread, there seemed to be a general consensus = that > your patch series should be applied. Could you work up a single > squashed patch to apply? There's so many patches with different > variations that it's difficult to tell which ones should be applied. Thanks for following up on this! I was planning to do so after the release of 27.1, but somehow never found the time. Here is the squashed patch using read-char-from-minibuffer (which unless I messed something up should be the same as the one from December[1]). --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Tweak-dired-warning-about-wildcard-characters.patch >From 135465cb28a8cfc2059754b7ab2c188864eb891d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 18 Dec 2019 07:54:01 +0100 Subject: [PATCH] Tweak dired warning about "wildcard" characters Non-isolated '?' and '*' characters may be quoted, or backslash-escaped; we do not know for a fact that the shell will interpret them as wildcards. Rephrase the prompt and offer to highlight the characters so that the user sees exactly what we are talking about. * lisp/dired-aux.el (dired-isolated-string-re): Use explicitly numbered groups. (dired--star-or-qmark-p): Add START parameter. Make sure to return the first isolated match. (dired--need-confirm-positions, dired--mark-positions) (dired--highlight-no-subst-chars, dired--no-subst-explain) (dired--no-subst-ask, dired--no-subst-confirm): New functions. (dired-do-shell-command): Use them. * test/lisp/dired-aux-tests.el (dired-test-bug27496): Adapt to new prompt. (dired-test--check-highlighting): New test helper. (dired-test-highlight-metachar): New tests. Co-authored-by: Noam Postavsky (bug#28969, bug#35564) --- lisp/dired-aux.el | 151 +++++++++++++++++++++++++++++------ test/lisp/dired-aux-tests.el | 45 ++++++++++- 2 files changed, 169 insertions(+), 27 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index cf2926ad37..df25a6418f 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -60,24 +60,132 @@ dired-isolated-string-re of a string followed/prefixed with an space. The regexp capture the preceding blank, STRING and the following blank as the groups 1, 2 and 3 respectively." - (format "\\(\\`\\|[ \t]\\)\\(%s\\)\\([ \t]\\|\\'\\)" string)) + (format "\\(?1:\\`\\|[ \t]\\)\\(?2:%s\\)\\(?3:[ \t]\\|\\'\\)" string)) -(defun dired--star-or-qmark-p (string match &optional keep) +(defun dired--star-or-qmark-p (string match &optional keep start) "Return non-nil if STRING contains isolated MATCH or `\\=`?\\=`'. MATCH should be the strings \"?\", `\\=`?\\=`', \"*\" or nil. The latter means STRING contains either \"?\" or `\\=`?\\=`' or \"*\". If optional arg KEEP is non-nil, then preserve the match data. Otherwise, this function changes it and saves MATCH as the second match group. +START is the position to start matching from. Isolated means that MATCH is surrounded by spaces or at the beginning/end of STRING followed/prefixed with an space. A match to `\\=`?\\=`', isolated or not, is also valid." - (let ((regexps (list (dired-isolated-string-re (if match (regexp-quote match) "[*?]"))))) + (let ((regexp (dired-isolated-string-re (if match (regexp-quote match) "[*?]")))) (when (or (null match) (equal match "?")) - (setq regexps (append (list "\\(\\)\\(`\\?`\\)\\(\\)") regexps))) - (cl-some (lambda (x) - (funcall (if keep #'string-match-p #'string-match) x string)) - regexps))) + (cl-callf concat regexp "\\|\\(?1:\\)\\(?2:`\\?`\\)\\(?3:\\)")) + (funcall (if keep #'string-match-p #'string-match) regexp string start))) + +(defun dired--need-confirm-positions (command string) + "Search for non-isolated matches of STRING in COMMAND. +Return a list of positions that match STRING, but would not be +considered \"isolated\" by `dired--star-or-qmark-p'." + (cl-assert (= (length string) 1)) + (let ((start 0) + (isolated-char-positions nil) + (confirm-positions nil) + (regexp (regexp-quote string))) + ;; Collect all ? and * surrounded by spaces and `?`. + (while (dired--star-or-qmark-p command string nil start) + (push (cons (match-beginning 2) (match-end 2)) + isolated-char-positions) + (setq start (match-end 2))) + ;; Now collect any remaining ? and *. + (setq start 0) + (while (string-match regexp command start) + (unless (cl-member (match-beginning 0) isolated-char-positions + :test (lambda (pos match) + (<= (car match) pos (cdr match)))) + (push (match-beginning 0) confirm-positions)) + (setq start (match-end 0))) + confirm-positions)) + +(defun dired--mark-positions (positions) + (let ((markers (make-string + (1+ (apply #'max positions)) + ?\s))) + (dolist (pos positions) + (setf (aref markers pos) ?^)) + markers)) + +(defun dired--highlight-no-subst-chars (positions command mark) + (cl-callf substring-no-properties command) + (dolist (pos positions) + (add-face-text-property pos (1+ pos) 'warning nil command)) + (if mark + (concat command "\n" (dired--mark-positions positions)) + command)) + +(defun dired--no-subst-explain (buf char-positions command mark-positions) + (with-current-buffer buf + (erase-buffer) + (insert + (format-message "\ +If your command contains occurrences of `*' surrounded by +whitespace, `dired-do-shell-command' substitutes them for the +entire file list to process. Otherwise, if your command contains +occurrences of `?' surrounded by whitespace or `%s', Dired will +run the command once for each file, substituting `?' for each +file name. + +Your command contains occurrences of `%s' that will not be +substituted, and will be passed through normally to the shell. + +%s + +(Press ^ to %s markers below these occurrences.) +" + "`" + (string (aref command (car char-positions))) + (dired--highlight-no-subst-chars char-positions command mark-positions) + (if mark-positions "remove" "add"))))) + +(defun dired--no-subst-ask (char nb-occur details) + (let ((hilit-char (propertize (string char) 'face 'warning)) + (choices `(?y ?n ?? ,@(when details '(?^))))) + (read-char-from-minibuffer + (format-message + (ngettext + "%d occurrence of `%s' will not be substituted. Proceed? (%s) " + "%d occurrences of `%s' will not be substituted. Proceed? (%s) " + nb-occur) + nb-occur hilit-char (mapconcat #'string choices ", ")) + choices))) + +(defun dired--no-subst-confirm (char-positions command) + (let ((help-buf (get-buffer-create "*Dired help*")) + (char (aref command (car char-positions))) + (nb-occur (length char-positions)) + (done nil) + (details nil) + (markers nil) + proceed) + (unwind-protect + (save-window-excursion + (while (not done) + (cl-case (dired--no-subst-ask char nb-occur details) + (?y + (setq done t + proceed t)) + (?n + (setq done t + proceed nil)) + (?? + (if details + (progn + (quit-window nil details) + (setq details nil)) + (dired--no-subst-explain + help-buf char-positions command markers) + (setq details (display-buffer help-buf)))) + (?^ + (setq markers (not markers)) + (dired--no-subst-explain + help-buf char-positions command markers))))) + (kill-buffer help-buf)) + proceed)) ;;;###autoload (defun dired-diff (file &optional switches) @@ -772,28 +880,19 @@ dired-do-shell-command (dired-read-shell-command "! on %s: " current-prefix-arg files) current-prefix-arg files))) - (cl-flet ((need-confirm-p - (cmd str) - (let ((res cmd) - (regexp (regexp-quote str))) - ;; Drop all ? and * surrounded by spaces and `?`. - (while (and (string-match regexp res) - (dired--star-or-qmark-p res str)) - (setq res (replace-match "" t t res 2))) - (string-match regexp res)))) (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep))) (no-subst (not (dired--star-or-qmark-p command "?" 'keep))) + (confirmations nil) ;; Get confirmation for wildcards that may have been meant ;; to control substitution of a file name or the file name list. - (ok (cond ((not (or on-each no-subst)) - (error "You can not combine `*' and `?' substitution marks")) - ((need-confirm-p command "*") - (y-or-n-p (format-message - "Confirm--do you mean to use `*' as a wildcard? "))) - ((need-confirm-p command "?") - (y-or-n-p (format-message - "Confirm--do you mean to use `?' as a wildcard? "))) - (t)))) + (ok (cond + ((not (or on-each no-subst)) + (error "You can not combine `*' and `?' substitution marks")) + ((setq confirmations (dired--need-confirm-positions command "*")) + (dired--no-subst-confirm confirmations command)) + ((setq confirmations (dired--need-confirm-positions command "?")) + (dired--no-subst-confirm confirmations command)) + (t)))) (cond ((not ok) (message "Command canceled")) (t (if on-each @@ -804,7 +903,7 @@ dired-do-shell-command nil file-list) ;; execute the shell command (dired-run-shell-command - (dired-shell-stuff-it command file-list nil arg)))))))) + (dired-shell-stuff-it command file-list nil arg))))))) ;; Might use {,} for bash or csh: (defvar dired-mark-prefix "" diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index 1fe155718d..54ec5d673c 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -28,7 +28,7 @@ dired-test-bug27496 (let* ((foo (make-temp-file "foo")) (files (list foo))) (unwind-protect - (cl-letf (((symbol-function 'y-or-n-p) 'error)) + (cl-letf (((symbol-function 'read-char-from-minibuffer) 'error)) (dired temporary-file-directory) (dired-goto-file foo) ;; `dired-do-shell-command' returns nil on success. @@ -114,6 +114,49 @@ dired-test-bug30624 (mapc #'delete-file `(,file1 ,file2)) (kill-buffer buf))))) +(defun dired-test--check-highlighting (command positions) + (let ((start 1)) + (dolist (pos positions) + (should-not (text-property-not-all start (1- pos) 'face nil command)) + (should (equal 'warning (get-text-property pos 'face command))) + (setq start (1+ pos))) + (should-not (text-property-not-all + start (length command) 'face nil command)))) + +(ert-deftest dired-test-highlight-metachar () + "Check that non-isolated meta-characters are highlighted." + (let* ((command "sed -r -e 's/oo?/a/' -e 's/oo?/a/' ? `?`") + (markers " ^ ^") + (result (dired--highlight-no-subst-chars + (dired--need-confirm-positions command "?") + command + t)) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(15 29))) + ;; Note that `?` is considered isolated, but `*` is not. + (let* ((command "sed -e 's/o*/a/' -e 's/o`*` /a/'") + (markers " ^ ^") + (result (dired--highlight-no-subst-chars + (dired--need-confirm-positions command "*") + command + t)) + (lines (split-string result "\n"))) + (should (= (length lines) 2)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (should (string-match (regexp-quote markers) (nth 1 lines))) + (dired-test--check-highlighting (nth 0 lines) '(11 25))) + (let* ((command "sed 's/\\?/!/'") + (result (dired--highlight-no-subst-chars + (dired--need-confirm-positions command "?") + command + nil)) + (lines (split-string result "\n"))) + (should (= (length lines) 1)) + (should (string-match (regexp-quote command) (nth 0 lines))) + (dired-test--check-highlighting (nth 0 lines) '(8)))) (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here -- 2.20.1 --=-=-= Content-Type: text/plain [1] --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sun Sep 20 08:18:43 2020 Received: (at 35564) by debbugs.gnu.org; 20 Sep 2020 12:18:43 +0000 Received: from localhost ([127.0.0.1]:49100 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJyIl-0002wa-BK for submit@debbugs.gnu.org; Sun, 20 Sep 2020 08:18:43 -0400 Received: from quimby.gnus.org ([95.216.78.240]:60210) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJyIg-0002wI-CV for 35564@debbugs.gnu.org; Sun, 20 Sep 2020 08:18:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Message-ID :In-Reply-To:Date:References:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=qKYOmzkeCaPLlRAbvYynTYpbALyYH2uwuCPVl+a9o3w=; b=MIqBE70hzOzPanygp3vZ8mAwMw osy7Nz89aI7Y+3QCCQTh5bRZup6xDKFDD/vOSLHjTgJLNO8/MupvXRjck00z+yGGv0QSOn6Ka6BUH f+7hdfaNza6kNikrq0+jXXoqHcPcznSPZcdwml8ISi7kxVVBpZY6ooTTZbbURoEHE7UA=; Received: from cm-84.212.202.86.getinternet.no ([84.212.202.86] helo=xo) by quimby with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kJyIQ-0007WD-S0; Sun, 20 Sep 2020 14:18:25 +0200 From: Lars Ingebrigtsen To: =?utf-8?Q?K=C3=A9vin?= Le Gouguec Subject: Re: bug#35564: [PATCH v5] Tweak dired warning about "wildcard" characters References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> <87h88cvpkj.fsf_-_@gmail.com> <87imsinbmr.fsf_-_@gmail.com> <87o8yoign9.fsf_-_@gmail.com> <87a77qhzvm.fsf@gmail.com> <87v9qcf00w.fsf@mail.linkov.net> <875zian2wg.fsf@gmail.com> <8336de17gr.fsf@gnu.org> <87ft7coeru.fsf@gnus.org> <87o8m04psz.fsf@gmail.com> X-Now-Playing: 808 State's _Ninety_: "808080808" Date: Sun, 20 Sep 2020 14:18:21 +0200 In-Reply-To: <87o8m04psz.fsf@gmail.com> (=?utf-8?Q?=22K=C3=A9vin?= Le Gouguec"'s message of "Sun, 20 Sep 2020 14:04:44 +0200") Message-ID: <87a6xkod4i.fsf@gnus.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Report: Spam detection software, running on the system "quimby.gnus.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: Kévin Le Gouguec writes: > Here is the squashed patch using read-char-from-minibuffer (which unless > I messed something up should be the same as the one from December[1]). Content analysis details: (-2.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 35564 Cc: michael_heerdegen@web.de, 35564@debbugs.gnu.org, npostavs@gmail.com, juri@linkov.net, monnier@iro.umontreal.ca, Eli Zaretskii , drew.adams@oracle.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) K=C3=A9vin Le Gouguec writes: > Here is the squashed patch using read-char-from-minibuffer (which unless > I messed something up should be the same as the one from December[1]). Thanks for the speedy squash. :-) I've now applied it to Emacs 28 after some extremely light testing. --=20 (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no From debbugs-submit-bounces@debbugs.gnu.org Sun Sep 20 08:18:54 2020 Received: (at control) by debbugs.gnu.org; 20 Sep 2020 12:18:54 +0000 Received: from localhost ([127.0.0.1]:49103 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJyIw-0002wy-Hh for submit@debbugs.gnu.org; Sun, 20 Sep 2020 08:18:54 -0400 Received: from quimby.gnus.org ([95.216.78.240]:60238) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJyIu-0002wk-S9 for control@debbugs.gnu.org; Sun, 20 Sep 2020 08:18:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Subject:From:To:Message-Id:Date:Sender:Reply-To:Cc: MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Vi6OpSY4FjlyaohjeOd1WfrhEWDME8PextfEYBJaGbo=; b=aGNyqE+UMUY7083Z9+8fD6ROrz klAsPt6WPN9x+cWstgCBXljWyHOUClO7nIh8+1cd0aldR1vtldVyMnjypnoFncuJrvUhziJ2lXSEv DXNtDRcPtuOtMSbijVS+c8nDgrV4fDfEloN25rrDbFHcSVODkmj5rnK5ipQbenAOFuxM=; Received: from cm-84.212.202.86.getinternet.no ([84.212.202.86] helo=xo) by quimby with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kJyIn-0007WZ-6C for control@debbugs.gnu.org; Sun, 20 Sep 2020 14:18:47 +0200 Date: Sun, 20 Sep 2020 14:18:43 +0200 Message-Id: <878sd4od3w.fsf@gnus.org> To: control@debbugs.gnu.org From: Lars Ingebrigtsen Subject: control message for bug #35564 X-Spam-Report: Spam detection software, running on the system "quimby.gnus.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: tags 35564 fixed close 35564 28.1 quit Content analysis details: (-2.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) tags 35564 fixed close 35564 28.1 quit From unknown Mon Aug 11 12:53:51 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Mon, 19 Oct 2020 11:24:07 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator