From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Daniel =?UTF-8?Q?Mart=C3=ADn?= via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#45412: File ... is large (... MiB), really open? (y)es or (n)o or (l)iterally Date: Thu, 06 May 2021 01:10:08 +0200 Message-ID: References: <87k0t72rhd.5.fsf@jidanni.org> <8735zuig9m.fsf@gnus.org> <87wnx62rpe.fsf@mail.linkov.net> <877dl80vwk.fsf@gnus.org> <87mttxqgnv.fsf@gnus.org> <83fsziprdf.fsf@gnu.org> <877dkqjhwd.fsf@gnus.org> <87zgxk1qlm.fsf@gnus.org> Reply-To: Daniel =?UTF-8?Q?Mart=C3=ADn?= Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="38870"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (darwin) Cc: 45412@debbugs.gnu.org, Eli Zaretskii , juri@linkov.net, jidanni@jidanni.org To: Lars Ingebrigtsen Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu May 06 01:11:40 2021 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1leQg8-000A0Q-Bx for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 06 May 2021 01:11:40 +0200 Original-Received: from localhost ([::1]:58098 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1leQg6-0002ne-Pk for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 05 May 2021 19:11:38 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:33884) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1leQfW-0002Fg-Sd for bug-gnu-emacs@gnu.org; Wed, 05 May 2021 19:11:03 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:51804) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1leQfW-00011B-H0 for bug-gnu-emacs@gnu.org; Wed, 05 May 2021 19:11:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1leQfW-0005iz-Cg for bug-gnu-emacs@gnu.org; Wed, 05 May 2021 19:11:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Daniel =?UTF-8?Q?Mart=C3=ADn?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 05 May 2021 23:11:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 45412 X-GNU-PR-Package: emacs Original-Received: via spool by 45412-submit@debbugs.gnu.org id=B45412.162025622321984 (code B ref 45412); Wed, 05 May 2021 23:11:02 +0000 Original-Received: (at 45412) by debbugs.gnu.org; 5 May 2021 23:10:23 +0000 Original-Received: from localhost ([127.0.0.1]:35112 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1leQes-0005iR-PC for submit@debbugs.gnu.org; Wed, 05 May 2021 19:10:23 -0400 Original-Received: from sonic311-32.consmr.mail.ir2.yahoo.com ([77.238.176.164]:35642) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1leQeq-0005iB-Qe for 45412@debbugs.gnu.org; Wed, 05 May 2021 19:10:21 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.es; s=s2048; t=1620256215; bh=fcLe8iXifAXij/Gq3tL6VKytKbXfiagceAIVvvFORJM=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=l+be5uYa6h+9EUzg2TXTFU3dMrn7ac43CLcv0CcTVieC+oWuwv3aX1z+qAXrGAPi6Iop8TS2VppMIdcFG9t4U7YhQAxNq095QlM1bcoNn0gBLfCE2US65bNSPe1nxpvo3aQxtVKGpz0hMDJyzVAqCkNmRH6JZPoZfUcm8WqHMStVAHwf3bsFz7czYFEJ6BUjr+N0Jsus1r9Hgban+FoljEBt3iBV7ipNZKuvTlHi60jZxPCoMOqMAQLJfX5K5gO0xQauxhT1nQKu7SXKnnjrYKwr2n6ZG/Fx0sqXOU2ZF2AA7Qio+izO8ZCiVpv8AfTOPp40EH++xVMIWd7EzjZczg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1620256215; bh=ecRm3Z+Bzt0Qb/UyRo4C5QZNsXtgodX3bd4MP1ZFoo+=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=qSCN0fcOB7SGAOmieBQPDgr6JHp/1cP5H1OPrUo1vSHmfFxiadzA4wTf8BcNnvFXjEzfizX5yzykFoC+srWSlqrL+2kZHGNp2E4jRq5dLgc9KNB5gropRvVTT9g6u2GK88/wYI+tloFFZeVFbshLekh8YhOOTSl2wELX352D+JGBUpVUoiN4WYHcrxJ/GBXUIYRxmhMXOncaZhjvOSehaD4X6uYRC1oggbqi53fuqi79YjhUCyQ4QZ2EGxg/Eca/WeukNhxETiD6ZeHkx90tMs2eBs/yzX2WiQge9gpYwOq0KP89Vy8H66QPdV9qTnLQa8c35q2d3GzeFWVod8w7Cw== X-YMail-OSG: d2s10EEVM1nQeDiG.2aw2RYLNNuiGuUF7hkyihUAqnWLC730OKT.A8d_o89VwLZ uQduNI9nydE2VudWFIDnhAJN60cqabnHzp5J_u5hp0bgDVM7CltsckBiwXK4mDWSK9tAXSjj5.x8 wiS7fqZ0L6ozZg6nWjKH_x6cP.C7N3Y11Z9sanrWo4y0u0VlT6.sdxzkXJ5Piq7cHXc107Ly2E9G BeZyy3nXJw.P13DN.S0FmBHNGoNtvZn5L5p2dt7CL.5EpPbAvNgJnXQ6Ca4IIQil1m8vokITXcmM 95nE6F.aQ7cfBWcK4EFod4f0M4WGaLnYV2xo6GYXz7c2myZn4zKI8LEyAoSB2aV80c1LMhGp_.2g MYvT625.koinRqBODZGKSjZ5bkHSjjSIHwXtTW_NquTcJ4ID7guW9ginheEFhAJf9cOVdnOMa3XY aL7Z991wG83Qy2dM6as2WizJ3yaFZwyDCZwFVV1AbCWqHrrm6iNHsu4qf9rsCw0ZRMzINx5d2Tla 0t4r_JUxayb4KrbCkaCOHRI0xj8Brtxse4UTuWnZns5dfZyMjvPyniOUg38UxOm9wTtuyxIXXIRc HQ6xBJAKXUxfz32bd4lO2p3jA.FvtT_pMf7aYh0Nu2KuEZ4irdr5qX.Dyy3zfjYhAGefTKjKsDL5 IijPbjK0ci6sX99jc9ftihkyVhDpAYDVbIXtzjcwMhBrc7Ro4ej0TgDfLW2fHe1LZ9AnFzEw.9Ht iXzhF2EOtvERo4nGlsXmKChnJ5JpATBh_6an9mcNNEEdqlccxmCN6H3vBlHFjem3mx747rCLpZpM 3UmTaZYD1yTDFVM2_VLPfXYw69JRCfV.VbVhfdtPs3 X-Sonic-MF: Original-Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.ir2.yahoo.com with HTTP; Wed, 5 May 2021 23:10:15 +0000 Original-Received: by kubenode529.mail-prod1.omega.ir2.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 54b3675188ff72355df76497d259a82f; Wed, 05 May 2021 23:10:09 +0000 (UTC) In-Reply-To: <87zgxk1qlm.fsf@gnus.org> (Lars Ingebrigtsen's message of "Tue, 27 Apr 2021 03:08:37 +0200") X-Mailer: WebService/1.1.18231 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Apache-HttpAsyncClient/4.1.4 (Java/16) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:205745 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Lars Ingebrigtsen writes: > Daniel Mart=C3=ADn writes: > >> Yes, if you click on a large file in Dired, you'll see a graphical >> prompt, as always. > > Right. Eli had other comments on the patch, though -- would it be > possible for you to rework the patch, and then we can get it applied? I think I've applied all code review suggestions (patches attached). Thanks. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Extend-read-multiple-choice-to-support-free-form-hel.patch >From b5a49005af33d8fcd35ca034949920f3ff8c36d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=ADn?= Date: Wed, 21 Apr 2021 23:14:27 +0200 Subject: [PATCH 1/2] Extend read-multiple-choice to support free-form help descriptions * lisp/emacs-lisp/rmc.el (read-multiple-choice): Add a new argument to override the default help description in `read-multiple-choice'. Use the `help-char' variable instead of ?\C-h. Also support the `edit' action from `query-replace-map', so that help links can be visited by entering a recursive edit. --- lisp/emacs-lisp/rmc.el | 129 +++++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 55 deletions(-) diff --git a/lisp/emacs-lisp/rmc.el b/lisp/emacs-lisp/rmc.el index bedf598d44..6aa169c032 100644 --- a/lisp/emacs-lisp/rmc.el +++ b/lisp/emacs-lisp/rmc.el @@ -26,24 +26,32 @@ (require 'seq) ;;;###autoload -(defun read-multiple-choice (prompt choices) +(defun read-multiple-choice (prompt choices &optional help-string) "Ask user a multiple choice question. PROMPT should be a string that will be displayed as the prompt. CHOICES is a list of (KEY NAME [DESCRIPTION]). KEY is a character to be entered. NAME is a short name for the entry to be displayed while prompting (if there's room, it might be -shortened). DESCRIPTION is an optional longer explanation that -will be displayed in a help buffer if the user requests more -help. +shortened). DESCRIPTION is an optional longer explanation for +the entry that will be displayed in a help buffer if the user +requests more help. This help description has a fixed format in +columns, but, for greater flexibility, instead of passing a +DESCRIPTION, the user can use the optional argument HELP-STRING. +This argument is a string that contains the text with the +complete description of all choices. `read-multiple-choice' will +display that description in a help buffer if the user requests +it. This function translates user input into responses by consulting the bindings in `query-replace-map'; see the documentation of that variable for more information. In this case, the useful -bindings are `recenter', `scroll-up', and `scroll-down'. If the -user enters `recenter', `scroll-up', or `scroll-down' responses, -perform the requested window recentering or scrolling and ask -again. +bindings are `recenter', `scroll-up', `scroll-down', and `edit'. +If the user enters `recenter', `scroll-up', or `scroll-down' +responses, perform the requested window recentering or scrolling +and ask again. If the user enters `edit', start a recursive +edit. When the user exit the recursive edit, the multiple choice +prompt gains focus again. When `use-dialog-box' is t (the default), this function can pop up a dialog window to collect the user input. That functionality @@ -133,6 +141,13 @@ read-multiple-choice (ignore-errors (scroll-other-window)) t) ((eq answer 'scroll-other-window-down) (ignore-errors (scroll-other-window-down)) t) + ((eq answer 'edit) + (save-match-data + (save-excursion + (message "%s" + (substitute-command-keys + "Recursive edit. Resume with \\[exit-recursive-edit]")) + (recursive-edit)))) (t tchar))) (when (eq tchar t) (setq wrong-char nil @@ -141,57 +156,61 @@ read-multiple-choice ;; help messages. (when (and (not (eq tchar nil)) (not (assq tchar choices))) - (setq wrong-char (not (memq tchar '(?? ?\C-h))) + (setq wrong-char (not (memq tchar `(?? ,help-char))) tchar nil) (when wrong-char (ding)) - (with-help-window (setq buf (get-buffer-create - "*Multiple Choice Help*")) - (with-current-buffer buf - (erase-buffer) - (pop-to-buffer buf) - (insert prompt "\n\n") - (let* ((columns (/ (window-width) 25)) - (fill-column 21) - (times 0) - (start (point))) - (dolist (elem choices) - (goto-char start) - (unless (zerop times) - (if (zerop (mod times columns)) - ;; Go to the next "line". - (goto-char (setq start (point-max))) - ;; Add padding. - (while (not (eobp)) - (end-of-line) - (insert (make-string (max (- (* (mod times columns) - (+ fill-column 4)) - (current-column)) - 0) - ?\s)) - (forward-line 1)))) - (setq times (1+ times)) - (let ((text - (with-temp-buffer - (insert (format - "%c: %s\n" - (car elem) - (cdr (assq (car elem) altered-names)))) - (fill-region (point-min) (point-max)) - (when (nth 2 elem) - (let ((start (point))) - (insert (nth 2 elem)) - (unless (bolp) - (insert "\n")) - (fill-region start (point-max)))) - (buffer-string)))) + (setq buf (get-buffer-create "*Multiple Choice Help*")) + (if (stringp help-string) + (with-help-window buf + (with-current-buffer buf + (insert help-string))) + (with-help-window buf + (with-current-buffer buf + (erase-buffer) + (pop-to-buffer buf) + (insert prompt "\n\n") + (let* ((columns (/ (window-width) 25)) + (fill-column 21) + (times 0) + (start (point))) + (dolist (elem choices) (goto-char start) - (dolist (line (split-string text "\n")) - (end-of-line) - (if (bolp) - (insert line "\n") - (insert line)) - (forward-line 1))))))))))) + (unless (zerop times) + (if (zerop (mod times columns)) + ;; Go to the next "line". + (goto-char (setq start (point-max))) + ;; Add padding. + (while (not (eobp)) + (end-of-line) + (insert (make-string (max (- (* (mod times columns) + (+ fill-column 4)) + (current-column)) + 0) + ?\s)) + (forward-line 1)))) + (setq times (1+ times)) + (let ((text + (with-temp-buffer + (insert (format + "%c: %s\n" + (car elem) + (cdr (assq (car elem) altered-names)))) + (fill-region (point-min) (point-max)) + (when (nth 2 elem) + (let ((start (point))) + (insert (nth 2 elem)) + (unless (bolp) + (insert "\n")) + (fill-region start (point-max)))) + (buffer-string)))) + (goto-char start) + (dolist (line (split-string text "\n")) + (end-of-line) + (if (bolp) + (insert line "\n") + (insert line)) + (forward-line 1)))))))))))) (when (buffer-live-p buf) (kill-buffer buf)) (assq tchar choices))) -- 2.31.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-Add-a-help-option-to-the-open-large-files-prompt.patch >From 406990011fe26ee681597e25155ab4dfa4f6ee42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=ADn?= Date: Wed, 21 Apr 2021 23:27:13 +0200 Subject: [PATCH 2/2] Add a help option to the open large files prompt * lisp/files.el (files--ask-user-about-large-file-help-text): New function that returns information about opening large files in Emacs. (Bug#45412) (files--ask-user-about-large-file): Use read-multiple-choice to display the available actions. * etc/NEWS: Advertise the new feature. --- etc/NEWS | 8 +++++++ lisp/files.el | 60 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index c2db98ae45..f99dcae536 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -276,6 +276,14 @@ commands. The new keystrokes are 'C-x x g' ('revert-buffer'), ** Commands 'set-frame-width' and 'set-frame-height' can now get their input using the minibuffer. +--- +** New help window when Emacs prompts before opening a large file. +Commands like 'find-file' or 'visit-tags-table' ask to visit a file +normally or literally when the file is larger than a certain size (by +default, 9.5 MiB). Press '?' or 'C-h' in that prompt to read more +about the different options to visit a file, how you can disable the +prompt, and how you can tweak the file size threshold. + * Editing Changes in Emacs 28.1 diff --git a/lisp/files.el b/lisp/files.el index 8e8fbac8dc..c1857ba032 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2129,27 +2129,57 @@ out-of-memory-warning-percentage (declare-function x-popup-dialog "menu.c" (position contents &optional header)) +(defun files--ask-user-about-large-file-help-text (op-type size) + "Format the text that explains the options to open large files in Emacs. +OP-TYPE contains the kind of file operation that will be +performed. SIZE is the size of the large file." + (format + "The file that you want to %s is large (%s), which exceeds the + threshold above which Emacs asks for confirmation (%s). + + Large files may be slow to edit or navigate so Emacs asks you + before you try to %s such files. + + You can press: + 'y' to %s the file. + 'n' to abort, and not %s the file. + 'l' (the letter ell) to %s the file literally, which means that + Emacs will %s the file without doing any format or character code + conversion and in Fundamental mode, without loading any potentially + expensive features. + + You can customize the option `large-file-warning-threshold' to be the + file size, in bytes, from which Emacs will ask for confirmation. Set + it to nil to never request confirmation." + op-type + size + (funcall byte-count-to-string-function large-file-warning-threshold) + op-type + op-type + op-type + op-type + op-type)) + (defun files--ask-user-about-large-file (size op-type filename offer-raw) + "If file SIZE larger than `large-file-warning-threshold', allow user to abort. +OP-TYPE specifies the file operation being performed on FILENAME. +If OFFER-RAW is true, give user the additional option to open the +file literally." (let ((prompt (format "File %s is large (%s), really %s?" (file-name-nondirectory filename) (funcall byte-count-to-string-function size) op-type))) (if (not offer-raw) (if (y-or-n-p prompt) nil 'abort) - (let* ((use-dialog (and (display-popup-menus-p) - last-input-event - (listp last-nonmenu-event) - use-dialog-box)) - (choice - (if use-dialog - (x-popup-dialog t `(,prompt - ("Yes" . ?y) - ("No" . ?n) - ("Open literally" . ?l))) - (read-char-choice - (concat prompt " (y)es or (n)o or (l)iterally ") - '(?y ?Y ?n ?N ?l ?L))))) - (cond ((memq choice '(?y ?Y)) nil) - ((memq choice '(?l ?L)) 'raw) + (let* ((choice + (car + (read-multiple-choice prompt '((?y "yes") + (?n "no") + (?l "literally")) + (files--ask-user-about-large-file-help-text + op-type + (funcall byte-count-to-string-function size)))))) + (cond ((eq choice ?y) nil) + ((eq choice ?l) 'raw) (t 'abort)))))) (defun abort-if-file-too-large (size op-type filename &optional offer-raw) -- 2.31.0 --=-=-=--