From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Noam Postavsky Newsgroups: gmane.emacs.bugs Subject: bug#31782: 26.1; dired-recursive-deletes broken Date: Mon, 30 Jul 2018 21:39:12 -0400 Message-ID: <87va8w18vz.fsf@gmail.com> References: <834li9qlu3.fsf@gnu.org> <87po0vy8ja.fsf@gmail.com> <83in6n4drr.fsf@gnu.org> <87efh9wmaf.fsf@gmail.com> <87wov0uwai.fsf@gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1533001090 31159 195.159.176.226 (31 Jul 2018 01:38:10 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 31 Jul 2018 01:38:10 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) Cc: 31782@debbugs.gnu.org, Juri Linkov To: Leo Liu Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Jul 31 03:38:05 2018 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fkJbw-00080T-C5 for geb-bug-gnu-emacs@m.gmane.org; Tue, 31 Jul 2018 03:38:04 +0200 Original-Received: from localhost ([::1]:56607 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fkJe2-0008VN-SN for geb-bug-gnu-emacs@m.gmane.org; Mon, 30 Jul 2018 21:40:14 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:59588) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fkJdv-0008Rd-7w for bug-gnu-emacs@gnu.org; Mon, 30 Jul 2018 21:40:09 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fkJdr-0007ah-3d for bug-gnu-emacs@gnu.org; Mon, 30 Jul 2018 21:40:07 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:58803) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fkJdq-0007aM-Ku for bug-gnu-emacs@gnu.org; Mon, 30 Jul 2018 21:40:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1fkJdq-00064M-AH for bug-gnu-emacs@gnu.org; Mon, 30 Jul 2018 21:40:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Noam Postavsky Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 31 Jul 2018 01:40:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 31782 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 31782-submit@debbugs.gnu.org id=B31782.153300116523278 (code B ref 31782); Tue, 31 Jul 2018 01:40:02 +0000 Original-Received: (at 31782) by debbugs.gnu.org; 31 Jul 2018 01:39:25 +0000 Original-Received: from localhost ([127.0.0.1]:35588 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fkJdE-00063M-Rp for submit@debbugs.gnu.org; Mon, 30 Jul 2018 21:39:25 -0400 Original-Received: from mail-it0-f51.google.com ([209.85.214.51]:53140) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fkJdA-00062u-EO; Mon, 30 Jul 2018 21:39:21 -0400 Original-Received: by mail-it0-f51.google.com with SMTP id d9-v6so2083580itf.2; Mon, 30 Jul 2018 18:39:20 -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=X9U9/CEe2w7iRqaXbBUmws/fH+tVX8C8LAQYEVRdI5A=; b=cWAEjBD4TitgeltGGVtKRtCP8q0aSazgBD9HQcrxkggrY3jLZyhBiAPtzF0I7T1jlN o5cYvRVRYOg/n69rdxj+jjbzWcW7BXaa1Ev7mKgpyh9rTOD68ZXmbbWHmGLPi/4rrJEU MTr86sdrKUCOEE9hQLmCBrmWbtjx2KLUYcd9gYudGX3zlTcRa4ToH2abIyF04nzQswtR +HhA/N3SRhlUjxqgd/E3ehrvz1InXF/FKcqL2QToY6owZfjRKYMXpAGjHHZ7NHDBnuOg pTlK02au/Q+lZSnxNckBgRSLi2mCZ6ecdftrbeFRgalhX1ELC6el/lol/zaCv/1rAlfC yy1Q== 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=X9U9/CEe2w7iRqaXbBUmws/fH+tVX8C8LAQYEVRdI5A=; b=Gxh1FyFKohvnxLTJ2jr/T/8kz0uLBMffj3grd8fLFuZ1CCtuIUva46AnAuPuXiK+E7 OlJxb+e5+3+xRml5MXAI12Q0rm7N02KM7YotgzcrutgssgrtGLntNHuHc3vgXMMKxa4a 1vKGVVNfxcLiBGy7RkukRnXUD7W0LiyXQqK3mUiOvF1OqLVdG9uNx2LKwLz4QCSFkJAd mPkyVfmur+05cXGrCjxaQgAZXT8Oepd82RDGoMvcLwDARntq9jnGUflfNZlvbOr0yTbC BzI8tRf2ZiskCZctgNW7w1lzA3lUU6iow8zkqIqrfbd/2Bp8wtOX5N7i4JBYIL96Sv/r UkuQ== X-Gm-Message-State: AOUpUlGJPPnXal6Y4kn11i5lqqdAm1jyF+A5oO2TySKp/kEeucZQ2pQz /0jykL0R5FtzsT3wOz+THjt504VD X-Google-Smtp-Source: AAOMgpfzLY7RXQ9sVwUjA4SNjJbd2YRwIENHKlxvBg77eCvVm/8oeZT1ZB5ZViSA9v8A58x9Qh9opQ== X-Received: by 2002:a24:29cf:: with SMTP id p198-v6mr1358781itp.48.1533001154779; Mon, 30 Jul 2018 18:39:14 -0700 (PDT) Original-Received: from zebian (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.googlemail.com with ESMTPSA id i129-v6sm555351ita.28.2018.07.30.18.39.13 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 30 Jul 2018 18:39:14 -0700 (PDT) In-Reply-To: <87wov0uwai.fsf@gmail.com> (Noam Postavsky's message of "Fri, 15 Jun 2018 07:24:53 -0400") 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: 208.118.235.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:149091 Archived-At: --=-=-= Content-Type: text/plain tags 31782 + patch quit Noam Postavsky writes: > So, looking at the Bug#30073 fix, the new (currently being introduced in > Emacs 27) read-answer function looks pretty similar to > read-multiple-choice. Perhaps some sharing is in order? There are differences in both the interface and implementation which make it difficult to merge these, even though the functionality has some overlap. Maybe something could be done later, but for now we'll have to settle for taking it as is (modulo the fix for the standard value problem). Here is the backported patch: --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=0001-New-function-read-answer-bug-30073.patch Content-Description: patch >From 0cb77a6c47799a556f224176e5e122b276224328 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Sun, 21 Jan 2018 23:45:43 +0200 Subject: [PATCH] New function read-answer (bug#30073) * lisp/emacs-lisp/map-ynp.el (read-answer-short): New defcustom. (read-answer): New function. * etc/NEWS: Announce it. * lisp/dired.el (dired-delete-file): Use read-answer. (dired--yes-no-all-quit-help): Remove function. (dired-delete-help): Remove defconst. * lisp/subr.el (assoc-delete-all): New function. (backported from master, "New function read-answer (bug#30073)" and "Respect non-saved value of `read-short-answer' (Bug#31782)") --- etc/NEWS | 3 ++ lisp/dired.el | 41 +++------------ lisp/emacs-lisp/map-ynp.el | 128 +++++++++++++++++++++++++++++++++++++++++++++ lisp/subr.el | 15 ++++++ test/lisp/dired-tests.el | 22 ++++---- 5 files changed, 165 insertions(+), 44 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index a27d1b89ec..331d5767f7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -110,6 +110,9 @@ be removed prior using the changed 'shadow-*' commands. * Lisp Changes in Emacs 26.2 +** The new function 'read-answer' accepts either long or short answers +depending on the new customizable variable 'read-answer-short'. + * Changes in Emacs 26.2 on Non-Free Operating Systems diff --git a/lisp/dired.el b/lisp/dired.el index c421e51ffd..2520ed2a10 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -2995,37 +2995,6 @@ dired-recursive-deletes ;; Match anything but `.' and `..'. (defvar dired-re-no-dot "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*") -(defconst dired-delete-help - "Type: -`yes' to delete recursively the current directory, -`no' to skip to next, -`all' to delete all remaining directories with no more questions, -`quit' to exit, -`help' to show this help message.") - -(defun dired--yes-no-all-quit-help (prompt &optional help-msg) - "Ask a question with valid answers: yes, no, all, quit, help. -PROMPT must end with '? ', for instance, 'Delete it? '. -If optional arg HELP-MSG is non-nil, then is a message to show when -the user answers 'help'. Otherwise, default to `dired-delete-help'." - (let ((valid-answers (list "yes" "no" "all" "quit")) - (answer "") - (input-fn (lambda () - (read-string - (format "%s [yes, no, all, quit, help] " prompt))))) - (setq answer (funcall input-fn)) - (when (string= answer "help") - (with-help-window "*Help*" - (with-current-buffer "*Help*" - (insert (or help-msg dired-delete-help))))) - (while (not (member answer valid-answers)) - (unless (string= answer "help") - (beep) - (message "Please answer `yes' or `no' or `all' or `quit'") - (sleep-for 2)) - (setq answer (funcall input-fn))) - answer)) - ;; Delete file, possibly delete a directory and all its files. ;; This function is useful outside of dired. One could change its name ;; to e.g. recursive-delete-file and put it somewhere else. @@ -3055,11 +3024,17 @@ dired-delete-file "trash" "delete") (dired-make-relative file)))) - (pcase (dired--yes-no-all-quit-help prompt) ; Prompt user. + (pcase (read-answer + prompt + '(("yes" ?y "delete recursively the current directory") + ("no" ?n "skip to next") + ("all" ?! "delete all remaining directories with no more questions") + ("quit" ?q "exit"))) ('"all" (setq recursive 'always dired-recursive-deletes recursive)) ('"yes" (if (eq recursive 'top) (setq recursive 'always))) ('"no" (setq recursive nil)) - ('"quit" (keyboard-quit))))) + ('"quit" (keyboard-quit)) + (_ (keyboard-quit))))) ; catch all unknown answers (setq recursive nil)) ; Empty dir or recursive is nil. (delete-directory file recursive trash)))) diff --git a/lisp/emacs-lisp/map-ynp.el b/lisp/emacs-lisp/map-ynp.el index 2a7eddedad..a1489c66ed 100644 --- a/lisp/emacs-lisp/map-ynp.el +++ b/lisp/emacs-lisp/map-ynp.el @@ -256,4 +256,132 @@ map-y-or-n-p ;; Return the number of actions that were taken. actions)) + +;; read-answer is a general-purpose question-asker that supports +;; either long or short answers. + +;; For backward compatibility check if short y/n answers are preferred. +(defcustom read-answer-short 'auto + "Control whether `read-answer' accepts short answers. +If t, accept short (single key-press) answers to the question. +If nil, require long answers. If `auto', accept short answers if +the function cell of `yes-or-no-p' is set to `y-or-on-p'." + :type '(choice (const :tag "Accept short answers" t) + (const :tag "Require long answer" nil) + (const :tag "Guess preference" auto)) + :version "26.2" + :group 'minibuffer) + +(defconst read-answer-map--memoize (make-hash-table :weakness 'key :test 'equal)) + +(defun read-answer (question answers) + "Read an answer either as a complete word or its character abbreviation. +Ask user a question and accept an answer from the list of possible answers. + +QUESTION should end in a space; this function adds a list of answers to it. + +ANSWERS is an alist with elements in the following format: + (LONG-ANSWER SHORT-ANSWER HELP-MESSAGE) +where + LONG-ANSWER is a complete answer, + SHORT-ANSWER is an abbreviated one-character answer, + HELP-MESSAGE is a string describing the meaning of the answer. + +Example: + \\='((\"yes\" ?y \"perform the action\") + (\"no\" ?n \"skip to the next\") + (\"all\" ?! \"accept all remaining without more questions\") + (\"help\" ?h \"show help\") + (\"quit\" ?q \"exit\")) + +When `read-answer-short' is non-nil, accept short answers. + +Return a long answer even in case of accepting short ones. + +When `use-dialog-box' is t, pop up a dialog window to get user input." + (let* ((short (if (eq read-answer-short 'auto) + (eq (symbol-function 'yes-or-no-p) 'y-or-n-p) + read-answer-short)) + (answers-with-help + (if (assoc "help" answers) + answers + (append answers '(("help" ?? "show this help message"))))) + (answers-without-help + (assoc-delete-all "help" (copy-alist answers-with-help))) + (prompt + (format "%s(%s) " question + (mapconcat (lambda (a) + (if short + (format "%c" (nth 1 a)) + (nth 0 a))) + answers-with-help ", "))) + (message + (format "Please answer %s." + (mapconcat (lambda (a) + (format "`%s'" (if short + (string (nth 1 a)) + (nth 0 a)))) + answers-with-help " or "))) + (short-answer-map + (when short + (or (gethash answers read-answer-map--memoize) + (puthash answers + (let ((map (make-sparse-keymap))) + (set-keymap-parent map minibuffer-local-map) + (dolist (a answers-with-help) + (define-key map (vector (nth 1 a)) + (lambda () + (interactive) + (delete-minibuffer-contents) + (insert (nth 0 a)) + (exit-minibuffer)))) + (define-key map [remap self-insert-command] + (lambda () + (interactive) + (delete-minibuffer-contents) + (beep) + (message message) + (sleep-for 2))) + map) + read-answer-map--memoize)))) + answer) + (while (not (assoc (setq answer (downcase + (cond + ((and (display-popup-menus-p) + last-input-event ; not during startup + (listp last-nonmenu-event) + use-dialog-box) + (x-popup-dialog + t + (cons question + (mapcar (lambda (a) + (cons (capitalize (nth 0 a)) + (nth 0 a))) + answers-with-help)))) + (short + (read-from-minibuffer + prompt nil short-answer-map nil + 'yes-or-no-p-history)) + (t + (read-from-minibuffer + prompt nil nil nil + 'yes-or-no-p-history))))) + answers-without-help)) + (if (string= answer "help") + (with-help-window "*Help*" + (with-current-buffer "*Help*" + (insert "Type:\n" + (mapconcat + (lambda (a) + (format "`%s'%s to %s" + (if short (string (nth 1 a)) (nth 0 a)) + (if short (format " (%s)" (nth 0 a)) "") + (nth 2 a))) + answers-with-help ",\n") + ".\n"))) + (beep) + (message message) + (sleep-for 2))) + answer)) + ;;; map-ynp.el ends here diff --git a/lisp/subr.el b/lisp/subr.el index f8ac70edef..7582b6cdb8 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -705,6 +705,21 @@ member-ignore-case (setq list (cdr list))) list) +(defun assoc-delete-all (key alist) + "Delete from ALIST all elements whose car is `equal' to KEY. +Return the modified alist. +Elements of ALIST that are not conses are ignored." + (while (and (consp (car alist)) + (equal (car (car alist)) key)) + (setq alist (cdr alist))) + (let ((tail alist) tail-cdr) + (while (setq tail-cdr (cdr tail)) + (if (and (consp (car tail-cdr)) + (equal (car (car tail-cdr)) key)) + (setcdr tail (cdr tail-cdr)) + (setq tail tail-cdr)))) + alist) + (defun assq-delete-all (key alist) "Delete from ALIST all elements whose car is `eq' to KEY. Return the modified alist. diff --git a/test/lisp/dired-tests.el b/test/lisp/dired-tests.el index c0242137b3..bb0e1bc388 100644 --- a/test/lisp/dired-tests.el +++ b/test/lisp/dired-tests.el @@ -384,9 +384,9 @@ dired-test-with-temp-dirs (dired-test-with-temp-dirs 'just-empty-dirs (let (asked) - (advice-add 'dired--yes-no-all-quit-help + (advice-add 'read-answer :override - (lambda (_) (setq asked t) "") + (lambda (_q _a) (setq asked t) "") '((name . dired-test-bug27940-advice))) (dired default-directory) (dired-toggle-marks) @@ -395,44 +395,44 @@ dired-test-with-temp-dirs (progn (should-not asked) (should-not (dired-get-marked-files))) ; All dirs deleted. - (advice-remove 'dired--yes-no-all-quit-help 'dired-test-bug27940-advice)))) + (advice-remove 'read-answer 'dired-test-bug27940-advice)))) ;; Answer yes (dired-test-with-temp-dirs nil - (advice-add 'dired--yes-no-all-quit-help :override (lambda (_) "yes") + (advice-add 'read-answer :override (lambda (_q _a) "yes") '((name . dired-test-bug27940-advice))) (dired default-directory) (dired-toggle-marks) (dired-do-delete nil) (unwind-protect (should-not (dired-get-marked-files)) ; All dirs deleted. - (advice-remove 'dired--yes-no-all-quit-help 'dired-test-bug27940-advice))) + (advice-remove 'read-answer 'dired-test-bug27940-advice))) ;; Answer no (dired-test-with-temp-dirs nil - (advice-add 'dired--yes-no-all-quit-help :override (lambda (_) "no") + (advice-add 'read-answer :override (lambda (_q _a) "no") '((name . dired-test-bug27940-advice))) (dired default-directory) (dired-toggle-marks) (dired-do-delete nil) (unwind-protect (should (= 5 (length (dired-get-marked-files)))) ; Just the empty dirs deleted. - (advice-remove 'dired--yes-no-all-quit-help 'dired-test-bug27940-advice))) + (advice-remove 'read-answer 'dired-test-bug27940-advice))) ;; Answer all (dired-test-with-temp-dirs nil - (advice-add 'dired--yes-no-all-quit-help :override (lambda (_) "all") + (advice-add 'read-answer :override (lambda (_q _a) "all") '((name . dired-test-bug27940-advice))) (dired default-directory) (dired-toggle-marks) (dired-do-delete nil) (unwind-protect (should-not (dired-get-marked-files)) ; All dirs deleted. - (advice-remove 'dired--yes-no-all-quit-help 'dired-test-bug27940-advice))) + (advice-remove 'read-answer 'dired-test-bug27940-advice))) ;; Answer quit (dired-test-with-temp-dirs nil - (advice-add 'dired--yes-no-all-quit-help :override (lambda (_) "quit") + (advice-add 'read-answer :override (lambda (_q _a) "quit") '((name . dired-test-bug27940-advice))) (dired default-directory) (dired-toggle-marks) @@ -440,7 +440,7 @@ dired-test-with-temp-dirs (dired-do-delete nil)) (unwind-protect (should (= 6 (length (dired-get-marked-files)))) ; All empty dirs but zeta-empty-dir deleted. - (advice-remove 'dired--yes-no-all-quit-help 'dired-test-bug27940-advice)))) + (advice-remove 'read-answer 'dired-test-bug27940-advice)))) (provide 'dired-tests) -- 2.11.0 --=-=-= Content-Type: text/plain I guess assoc-delete-all should be announced in NEWS too? Although it looks like it could be replaced with cl-delete instead. > Another thing is that the defcustom default value trick doesn't work as > intended (as far as I understand the intention, at least). > > ;; For backward compatibility check if short y/n answers are preferred. > (defcustom read-answer-short (eq (symbol-function 'yes-or-no-p) 'y-or-n-p) > "If non-nil, accept short answers to the question." > I think we'd want some `auto' setting which would tell read-answer to > look at the yes-or-no-p function value at run time. Here's a patch for that against master (I already included this into the backported patch above). --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-Respect-non-saved-value-of-read-short-answer-Bug-317.patch Content-Description: patch >From 1059db2520f1aa8d26d2cdb253c57421f647df2e Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Wed, 4 Jul 2018 22:51:45 -0400 Subject: [PATCH 1/2] Respect non-saved value of `read-short-answer' (Bug#31782) * lisp/emacs-lisp/map-ynp.el (read-answer-short): Add an `auto' setting. (read-answer): Check the function cell of `yes-or-no-p' when `read-answer-short' is `auto' rather than calling `custom-reevaluate-setting' which would reset the option to its saved value. --- lisp/emacs-lisp/map-ynp.el | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lisp/emacs-lisp/map-ynp.el b/lisp/emacs-lisp/map-ynp.el index 61c04ff7b3..c029c7e1b5 100644 --- a/lisp/emacs-lisp/map-ynp.el +++ b/lisp/emacs-lisp/map-ynp.el @@ -257,9 +257,14 @@ map-y-or-n-p ;; either long or short answers. ;; For backward compatibility check if short y/n answers are preferred. -(defcustom read-answer-short (eq (symbol-function 'yes-or-no-p) 'y-or-n-p) - "If non-nil, accept short answers to the question." - :type 'boolean +(defcustom read-answer-short 'auto + "Control whether `read-answer' accepts short answers. +If t, accept short (single key-press) answers to the question. +If nil, require long answers. If `auto', accept short answers if +the function cell of `yes-or-no-p' is set to `y-or-on-p'." + :type '(choice (const :tag "Accept short answers" t) + (const :tag "Require long answer" nil) + (const :tag "Guess preference" auto)) :version "27.1" :group 'minibuffer) @@ -290,8 +295,9 @@ read-answer Return a long answer even in case of accepting short ones. When `use-dialog-box' is t, pop up a dialog window to get user input." - (custom-reevaluate-setting 'read-answer-short) - (let* ((short read-answer-short) + (let* ((short (if (eq read-answer-short 'auto) + (eq (symbol-function 'yes-or-no-p) 'y-or-n-p) + read-answer-short)) (answers-with-help (if (assoc "help" answers) answers -- 2.11.0 --=-=-= Content-Type: text/plain And once backported, we should remove the announcement from 27.1 NEWS, since the new function it will already be introduced in 26.2: --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0002-etc-NEWS-Remove-read-answer-it-was-backported-to-v26.patch Content-Description: patch >From c791639c259abe6e514a4e3ffd62c904cff636e2 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Mon, 30 Jul 2018 21:02:07 -0400 Subject: [PATCH 2/2] ; etc/NEWS: Remove read-answer, it was backported to v26 --- etc/NEWS | 4 ---- 1 file changed, 4 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 5ca1b428de..2825bb9f59 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -913,10 +913,6 @@ higher-level functions. some years back. It now respects 'imagemagick-types-inhibit' as a way to disable that. -+++ -** The new function 'read-answer' accepts either long or short answers -depending on the new customizable variable 'read-answer-short'. - ** The function 'load' now behaves correctly when loading modules. Specifically, it puts the module name into 'load-history', prints loading messages if requested, and protects against recursive loads. -- 2.11.0 --=-=-=--