From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: =?UTF-8?Q?K=C3=A9vin?= Le Gouguec Newsgroups: gmane.emacs.bugs Subject: bug#35564: [PATCH v3] Tweak dired warning about "wildcard" characters Date: Wed, 26 Jun 2019 08:16:44 +0200 Message-ID: <87h88cvpkj.fsf_-_@gmail.com> References: <87zho2cd4f.fsf@gmail.com> <87wohvf22u.fsf@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="191241"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) Cc: Stefan Monnier , Noam Postavsky To: 35564@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Jun 26 08:17:32 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1hg1FJ-000neA-U2 for geb-bug-gnu-emacs@m.gmane.org; Wed, 26 Jun 2019 08:17:30 +0200 Original-Received: from localhost ([::1]:36992 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hg1FI-00044z-B5 for geb-bug-gnu-emacs@m.gmane.org; Wed, 26 Jun 2019 02:17:28 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:44376) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hg1Ex-00044l-0r for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 02:17:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hg1Eu-0003uZ-QQ for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 02:17:06 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:48817) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hg1Es-0003s4-Io for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 02:17:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1hg1Es-0002ar-CV for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 02:17:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: =?UTF-8?Q?K=C3=A9vin?= Le Gouguec Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 26 Jun 2019 06:17:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 35564 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 35564-submit@debbugs.gnu.org id=B35564.15615298169952 (code B ref 35564); Wed, 26 Jun 2019 06:17:02 +0000 Original-Received: (at 35564) by debbugs.gnu.org; 26 Jun 2019 06:16:56 +0000 Original-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 Original-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 Original-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) Original-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) In-Reply-To: <87wohvf22u.fsf@gmail.com> ("=?UTF-8?Q?K=C3=A9vin?= Le Gouguec"'s message of "Sun, 09 Jun 2019 13:08:41 +0200") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:161463 Archived-At: --=-=-= 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)) --=-=-=--