From unknown Fri Aug 15 19:22:12 2025 X-Loop: owner@emacsbugs.donarmstrong.com Subject: bug#2086: 23.0.60; Todo mode bug with completing-read + patch Reply-To: Stephen Berman , 2086@debbugs.gnu.org Resent-From: Stephen Berman Original-Sender: steve@escher.local.home Resent-To: bug-submit-list@lists.donarmstrong.com Resent-CC: Emacs Bugs Resent-Date: Tue, 27 Jan 2009 16:20:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-Emacs-PR-Message: report 2086 X-Emacs-PR-Package: emacs X-Emacs-PR-Keywords: Received: via spool by submit@emacsbugs.donarmstrong.com id=B.123307268330994 (code B ref -1); Tue, 27 Jan 2009 16:20:02 +0000 Received: (at submit) by emacsbugs.donarmstrong.com; 27 Jan 2009 16:11:23 +0000 X-Spam-Checker-Version: SpamAssassin 3.2.5-bugs.debian.org_2005_01_02 (2008-06-10) on rzlab.ucr.edu X-Spam-Level: X-Spam-Bayes: score:0.5 Bayes not run. spammytokens:Tokens not available. hammytokens:Tokens not available. X-Spam-Status: No, score=0.1 required=4.0 tests=FOURLA,MURPHY_DRUGS_REL8 autolearn=no version=3.2.5-bugs.debian.org_2005_01_02 Received: from fencepost.gnu.org (fencepost.gnu.org [140.186.70.10]) by rzlab.ucr.edu (8.13.8/8.13.8/Debian-3) with ESMTP id n0RGBJRV030988 for ; Tue, 27 Jan 2009 08:11:20 -0800 Received: from mail.gnu.org ([199.232.76.166]:60386 helo=mx10.gnu.org) by fencepost.gnu.org with esmtp (Exim 4.67) (envelope-from ) id 1LRqVQ-0001W8-OE for emacs-pretest-bug@gnu.org; Tue, 27 Jan 2009 11:09:41 -0500 Received: from Debian-exim by monty-python.gnu.org with spam-scanned (Exim 4.60) (envelope-from ) id 1LRqWx-0006Ba-7v for emacs-pretest-bug@gnu.org; Tue, 27 Jan 2009 11:11:18 -0500 Received: from mail.gmx.net ([213.165.64.20]:43937) by monty-python.gnu.org with smtp (Exim 4.60) (envelope-from ) id 1LRqWw-0006B2-IZ for emacs-pretest-bug@gnu.org; Tue, 27 Jan 2009 11:11:15 -0500 Received: (qmail invoked by alias); 27 Jan 2009 16:11:09 -0000 Received: from i59F57C0C.versanet.de (EHLO escher.local.home) [89.245.124.12] by mail.gmx.net (mp015) with SMTP; 27 Jan 2009 17:11:09 +0100 X-Authenticated: #20778731 X-Provags-ID: V01U2FsdGVkX1/oHrY9YOLo/hzztma+WSCgWxOPPYnMOjpKQDeGIn iT2IFpGeD51eej Received: by escher.local.home (Postfix, from userid 1000) id 3FF721D129F; Tue, 27 Jan 2009 17:11:03 +0100 (CET) From: Stephen Berman To: emacs-pretest-bug@gnu.org Date: Tue, 27 Jan 2009 16:48:11 +0100 Message-ID: <87pri8agxw.fsf@escher.local.home> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux) Sender: steve@escher.local.home MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Y-GMX-Trusted: 0 X-FuHaFi: 0.49 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. --=-=-= GNU Emacs 23.0.60.30 (i686-pc-linux-gnu, GTK+ Version 2.14.4) of 2009-01-21 on escher 1. emacs -Q 2. Type `M-x todo-show', and in the Todo mode buffer type `s' to save ~/.todo-do, then type the following sequence of Todo mode commands and input: `I item1 RET i item2 RET Newcat RET'. Widen the buffer and you see the following (modulo the time-stamp headers): -*- mode: todo; todo-categories: ("Newcat" "Todo"); -*- */* --- Newcat */* 2009-01-14 13:48 steve: item2 --- End */* --------------------------------------------------------------------------- */* --- Todo */* 2009-01-14 13:48 steve: item1 --- End */* --------------------------------------------------------------------------- 3. Now type `M-x customize-option RET history-delete-duplicates RET', toggle the value to `on (non-nil)' and save for the current session. 4. Type `M-x todo-show'. 5. In the Todo mode buffer, with category "Newcat" displayed, type `j' and at the prompt, type `Todo', to jump the the category "Todo". => Now category "Todo" is displayed, but it is empty. 6. Widen the Todo mode buffer, and this is what it now looks like: -*- mode: todo; todo-categories: ("Todo" "Newcat"); -*- */* --- Todo --- End */* --------------------------------------------------------------------------- */* --- Newcat */* 2009-01-14 13:48 steve: item2 --- End */* --------------------------------------------------------------------------- */* --- Todo */* 2009-01-14 13:48 steve: item1 --- End */* --------------------------------------------------------------------------- As a second example, after step 4 above do the following: 5'. While in category "Newcat", type `i item3 RET Todo RET' to insert "item3". => Now category "Todo" is displayed, but it contains only item3, not also item1. 6. Widen the Todo mode buffer, and this is what it now looks like: -*- mode: todo; todo-categories: ("Todo" "Newcat"); -*- */* --- Todo */* 2009-01-14 13:48 steve: item3 --- End */* --------------------------------------------------------------------------- */* --- Newcat */* 2009-01-14 13:48 steve: item2 --- End */* --------------------------------------------------------------------------- */* --- Todo */* 2009-01-14 13:48 steve: item1 --- End */* --------------------------------------------------------------------------- The problem in both cases is due, I believe, to the failure to make a copy of todo-categories before calling completing-read and to restore it afterwards. This is because, when history-delete-duplicates is non-nil, completing-read (via read_minibuf) destructively deletes the list element used as the completion and conses it on to the front, yielding a reordered list. The fix I propose, in the attached patch, is a wrapper for completing-read that copies and restores todo-categories as required. The wrapper is used instead of completing-read by todo-insert-item and todo-jump-to-category. (The resulting modularization also implements one to the "things to do" mentioned in the todo-mode.el commentary.) I also think the completing-read code in todo-mode.el should be simplified by replacing todo-category-alist. The doc string of the latter says: "Generate an alist for use in `completing-read' from `todo-categories'." AFAICS there is no need for this structure. The members of the alist, which constitutes the COLLECTION argument of completing-read, are just the single element lists of each category name. This provides no more information than the value of todo-categories itself, which as a list of strings is suitable for the COLLECTION argument. (Was there a time when completing-read took an alist but not a list of strings as the COLLECTION argument?) The wrapper uses todo-categories instead of todo-category-alist, so the patch eliminates the latter function from todo-mode.el. Finally, the patch makes the code of todo-insert-item conform to its doc string. The latter says: "With a prefix argument solicit the category, otherwise use the current category." But the code does just the opposite. I assume the desired behavior is as stated in the doc string. (In http://lists.gnu.org/archive/html/bug-gnu-emacs/2002-01/msg00543.html there was a patch that contained a fix for this, but it was not committed to CVS.) 2009-01-19 Stephen Berman * calendar/todo-mode.el (todo-category-alist): Delete. (todo-completing-read): New function. (todo-insert-item, todo-jump-to-category): Use it. (todo-insert-item): Make the use of the prefix argument conform to the doc string. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=todo-completing-read.diff Content-Description: Todo mode patch *** emacs/lisp/calendar/todo-mode.el.~1.72.~ 2009-01-09 11:48:58.000000000 +0100 --- emacs/lisp/calendar/todo-mode.el 2009-01-21 10:36:15.000000000 +0100 *************** *** 596,610 **** "New TODO entry: " (if todo-entry-prefix-function (funcall todo-entry-prefix-function))))) - (categories todo-categories) - (history (cons 'categories (1+ todo-category-number))) (current-category (nth todo-category-number todo-categories)) ! (category ! (if arg ! current-category ! (completing-read (concat "Category [" current-category "]: ") ! (todo-category-alist) nil nil nil ! history current-category)))) (todo-add-item-non-interactively new-item category)))) (defalias 'todo-cmd-inst 'todo-insert-item) --- 596,603 ---- "New TODO entry: " (if todo-entry-prefix-function (funcall todo-entry-prefix-function))))) (current-category (nth todo-category-number todo-categories)) ! (category (if arg (todo-completing-read) current-category))) (todo-add-item-non-interactively new-item category)))) (defalias 'todo-cmd-inst 'todo-insert-item) *************** *** 801,812 **** (defun todo-jump-to-category () "Jump to a category. Default is previous category." (interactive) ! (let* ((categories todo-categories) ! (history (cons 'categories (1+ todo-category-number))) ! (default (nth todo-category-number todo-categories)) ! (category (completing-read ! (concat "Category [" default "]: ") ! (todo-category-alist) nil nil nil history default))) (if (string= "" category) (setq category (nth todo-category-number todo-categories))) (setq todo-category-number --- 794,800 ---- (defun todo-jump-to-category () "Jump to a category. Default is previous category." (interactive) ! (let ((category (todo-completing-read))) (if (string= "" category) (setq category (nth todo-category-number todo-categories))) (setq todo-category-number *************** *** 861,869 **** "Return non-nil if STRING spans several lines." (> (todo-string-count-lines string) 1)) ! (defun todo-category-alist () ! "Generate an alist for use in `completing-read' from `todo-categories'." ! (mapcar #'list todo-categories)) ;; --------------------------------------------------------------------------- --- 849,867 ---- "Return non-nil if STRING spans several lines." (> (todo-string-count-lines string) 1)) ! (defun todo-completing-read () ! "Return a category name, with completion, for use in Todo mode." ! ;; make a copy of todo-categories in case history-delete-duplicates is ! ;; non-nil, which makes completing-read alter todo-categories ! (let* ((categories (copy-sequence todo-categories)) ! (history (cons 'todo-categories (1+ todo-category-number))) ! (default (nth todo-category-number todo-categories)) ! (category (completing-read ! (concat "Category [" default "]: ") ! todo-categories nil nil nil history default))) ! ;; restore the original value of todo-categories ! (setq todo-categories categories) ! category)) ;; --------------------------------------------------------------------------- --=-=-=-- From unknown Fri Aug 15 19:22:12 2025 MIME-Version: 1.0 X-Mailer: MIME-tools 5.420 (Entity 5.420) X-Loop: owner@emacsbugs.donarmstrong.com From: help-debbugs@gnu.org (Emacs bug Tracking System) To: Stephen Berman Subject: bug#2086 closed by Chong Yidong (Re: 23.0.60; Todo mode bug with completing-read + patch) Message-ID: References: <8763k0cc62.fsf@cyd.mit.edu> <87pri8agxw.fsf@escher.local.home> X-Emacs-PR-Message: they-closed 2086 X-Emacs-PR-Package: emacs Reply-To: 2086@debbugs.gnu.org Date: Wed, 28 Jan 2009 04:05:09 +0000 Content-Type: multipart/mixed; boundary="----------=_1233115510-16985-1" This is a multi-part message in MIME format... ------------=_1233115510-16985-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This is an automatic notification regarding your bug report which was filed against the emacs package: #2086: 23.0.60; Todo mode bug with completing-read + patch It has been closed by Chong Yidong . Their explanation is attached below along with your original report. If this explanation is unsatisfactory and you have not received a better one in a separate message then please contact Chong Yidong by replying to this email. --=20 2086: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D2086 Emacs Bug Tracking System Contact help-debbugs@gnu.org with problems ------------=_1233115510-16985-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at 2086-done) by emacsbugs.donarmstrong.com; 28 Jan 2009 04:00:09 +0000 X-Spam-Checker-Version: SpamAssassin 3.2.5-bugs.debian.org_2005_01_02 (2008-06-10) on rzlab.ucr.edu X-Spam-Level: X-Spam-Bayes: score:0.5 Bayes not run. spammytokens:Tokens not available. hammytokens:Tokens not available. X-Spam-Status: No, score=0.0 required=4.0 tests=MURPHY_DRUGS_REL8 autolearn=ham version=3.2.5-bugs.debian.org_2005_01_02 Received: from cyd.mit.edu (CYD.MIT.EDU [18.115.2.24]) by rzlab.ucr.edu (8.13.8/8.13.8/Debian-3) with ESMTP id n0S406TS014939 for <2086-done@emacsbugs.donarmstrong.com>; Tue, 27 Jan 2009 20:00:07 -0800 Received: by cyd.mit.edu (Postfix, from userid 1000) id 7995A57E205; Tue, 27 Jan 2009 23:00:37 -0500 (EST) From: Chong Yidong To: Stephen Berman Cc: 2086-done@debbugs.gnu.org Subject: Re: 23.0.60; Todo mode bug with completing-read + patch Date: Tue, 27 Jan 2009 23:00:37 -0500 Message-ID: <8763k0cc62.fsf@cyd.mit.edu> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii > The fix I propose, in the attached patch, is a wrapper for > completing-read that copies and restores todo-categories as required. > The wrapper is used instead of completing-read by todo-insert-item and > todo-jump-to-category. (The resulting modularization also implements > one to the "things to do" mentioned in the todo-mode.el commentary.) Applied, thanks. ------------=_1233115510-16985-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at submit) by emacsbugs.donarmstrong.com; 27 Jan 2009 16:11:23 +0000 X-Spam-Checker-Version: SpamAssassin 3.2.5-bugs.debian.org_2005_01_02 (2008-06-10) on rzlab.ucr.edu X-Spam-Level: X-Spam-Bayes: score:0.5 Bayes not run. spammytokens:Tokens not available. hammytokens:Tokens not available. X-Spam-Status: No, score=0.1 required=4.0 tests=FOURLA,MURPHY_DRUGS_REL8 autolearn=no version=3.2.5-bugs.debian.org_2005_01_02 Received: from fencepost.gnu.org (fencepost.gnu.org [140.186.70.10]) by rzlab.ucr.edu (8.13.8/8.13.8/Debian-3) with ESMTP id n0RGBJRV030988 for ; Tue, 27 Jan 2009 08:11:20 -0800 Received: from mail.gnu.org ([199.232.76.166]:60386 helo=mx10.gnu.org) by fencepost.gnu.org with esmtp (Exim 4.67) (envelope-from ) id 1LRqVQ-0001W8-OE for emacs-pretest-bug@gnu.org; Tue, 27 Jan 2009 11:09:41 -0500 Received: from Debian-exim by monty-python.gnu.org with spam-scanned (Exim 4.60) (envelope-from ) id 1LRqWx-0006Ba-7v for emacs-pretest-bug@gnu.org; Tue, 27 Jan 2009 11:11:18 -0500 Received: from mail.gmx.net ([213.165.64.20]:43937) by monty-python.gnu.org with smtp (Exim 4.60) (envelope-from ) id 1LRqWw-0006B2-IZ for emacs-pretest-bug@gnu.org; Tue, 27 Jan 2009 11:11:15 -0500 Received: (qmail invoked by alias); 27 Jan 2009 16:11:09 -0000 Received: from i59F57C0C.versanet.de (EHLO escher.local.home) [89.245.124.12] by mail.gmx.net (mp015) with SMTP; 27 Jan 2009 17:11:09 +0100 X-Authenticated: #20778731 X-Provags-ID: V01U2FsdGVkX1/oHrY9YOLo/hzztma+WSCgWxOPPYnMOjpKQDeGIn iT2IFpGeD51eej Received: by escher.local.home (Postfix, from userid 1000) id 3FF721D129F; Tue, 27 Jan 2009 17:11:03 +0100 (CET) From: Stephen Berman To: emacs-pretest-bug@gnu.org Subject: 23.0.60; Todo mode bug with completing-read + patch Date: Tue, 27 Jan 2009 16:48:11 +0100 Message-ID: <87pri8agxw.fsf@escher.local.home> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux) Sender: steve@escher.local.home MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Y-GMX-Trusted: 0 X-FuHaFi: 0.49 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. --=-=-= GNU Emacs 23.0.60.30 (i686-pc-linux-gnu, GTK+ Version 2.14.4) of 2009-01-21 on escher 1. emacs -Q 2. Type `M-x todo-show', and in the Todo mode buffer type `s' to save ~/.todo-do, then type the following sequence of Todo mode commands and input: `I item1 RET i item2 RET Newcat RET'. Widen the buffer and you see the following (modulo the time-stamp headers): -*- mode: todo; todo-categories: ("Newcat" "Todo"); -*- */* --- Newcat */* 2009-01-14 13:48 steve: item2 --- End */* --------------------------------------------------------------------------- */* --- Todo */* 2009-01-14 13:48 steve: item1 --- End */* --------------------------------------------------------------------------- 3. Now type `M-x customize-option RET history-delete-duplicates RET', toggle the value to `on (non-nil)' and save for the current session. 4. Type `M-x todo-show'. 5. In the Todo mode buffer, with category "Newcat" displayed, type `j' and at the prompt, type `Todo', to jump the the category "Todo". => Now category "Todo" is displayed, but it is empty. 6. Widen the Todo mode buffer, and this is what it now looks like: -*- mode: todo; todo-categories: ("Todo" "Newcat"); -*- */* --- Todo --- End */* --------------------------------------------------------------------------- */* --- Newcat */* 2009-01-14 13:48 steve: item2 --- End */* --------------------------------------------------------------------------- */* --- Todo */* 2009-01-14 13:48 steve: item1 --- End */* --------------------------------------------------------------------------- As a second example, after step 4 above do the following: 5'. While in category "Newcat", type `i item3 RET Todo RET' to insert "item3". => Now category "Todo" is displayed, but it contains only item3, not also item1. 6. Widen the Todo mode buffer, and this is what it now looks like: -*- mode: todo; todo-categories: ("Todo" "Newcat"); -*- */* --- Todo */* 2009-01-14 13:48 steve: item3 --- End */* --------------------------------------------------------------------------- */* --- Newcat */* 2009-01-14 13:48 steve: item2 --- End */* --------------------------------------------------------------------------- */* --- Todo */* 2009-01-14 13:48 steve: item1 --- End */* --------------------------------------------------------------------------- The problem in both cases is due, I believe, to the failure to make a copy of todo-categories before calling completing-read and to restore it afterwards. This is because, when history-delete-duplicates is non-nil, completing-read (via read_minibuf) destructively deletes the list element used as the completion and conses it on to the front, yielding a reordered list. The fix I propose, in the attached patch, is a wrapper for completing-read that copies and restores todo-categories as required. The wrapper is used instead of completing-read by todo-insert-item and todo-jump-to-category. (The resulting modularization also implements one to the "things to do" mentioned in the todo-mode.el commentary.) I also think the completing-read code in todo-mode.el should be simplified by replacing todo-category-alist. The doc string of the latter says: "Generate an alist for use in `completing-read' from `todo-categories'." AFAICS there is no need for this structure. The members of the alist, which constitutes the COLLECTION argument of completing-read, are just the single element lists of each category name. This provides no more information than the value of todo-categories itself, which as a list of strings is suitable for the COLLECTION argument. (Was there a time when completing-read took an alist but not a list of strings as the COLLECTION argument?) The wrapper uses todo-categories instead of todo-category-alist, so the patch eliminates the latter function from todo-mode.el. Finally, the patch makes the code of todo-insert-item conform to its doc string. The latter says: "With a prefix argument solicit the category, otherwise use the current category." But the code does just the opposite. I assume the desired behavior is as stated in the doc string. (In http://lists.gnu.org/archive/html/bug-gnu-emacs/2002-01/msg00543.html there was a patch that contained a fix for this, but it was not committed to CVS.) 2009-01-19 Stephen Berman * calendar/todo-mode.el (todo-category-alist): Delete. (todo-completing-read): New function. (todo-insert-item, todo-jump-to-category): Use it. (todo-insert-item): Make the use of the prefix argument conform to the doc string. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=todo-completing-read.diff Content-Description: Todo mode patch *** emacs/lisp/calendar/todo-mode.el.~1.72.~ 2009-01-09 11:48:58.000000000 +0100 --- emacs/lisp/calendar/todo-mode.el 2009-01-21 10:36:15.000000000 +0100 *************** *** 596,610 **** "New TODO entry: " (if todo-entry-prefix-function (funcall todo-entry-prefix-function))))) - (categories todo-categories) - (history (cons 'categories (1+ todo-category-number))) (current-category (nth todo-category-number todo-categories)) ! (category ! (if arg ! current-category ! (completing-read (concat "Category [" current-category "]: ") ! (todo-category-alist) nil nil nil ! history current-category)))) (todo-add-item-non-interactively new-item category)))) (defalias 'todo-cmd-inst 'todo-insert-item) --- 596,603 ---- "New TODO entry: " (if todo-entry-prefix-function (funcall todo-entry-prefix-function))))) (current-category (nth todo-category-number todo-categories)) ! (category (if arg (todo-completing-read) current-category))) (todo-add-item-non-interactively new-item category)))) (defalias 'todo-cmd-inst 'todo-insert-item) *************** *** 801,812 **** (defun todo-jump-to-category () "Jump to a category. Default is previous category." (interactive) ! (let* ((categories todo-categories) ! (history (cons 'categories (1+ todo-category-number))) ! (default (nth todo-category-number todo-categories)) ! (category (completing-read ! (concat "Category [" default "]: ") ! (todo-category-alist) nil nil nil history default))) (if (string= "" category) (setq category (nth todo-category-number todo-categories))) (setq todo-category-number --- 794,800 ---- (defun todo-jump-to-category () "Jump to a category. Default is previous category." (interactive) ! (let ((category (todo-completing-read))) (if (string= "" category) (setq category (nth todo-category-number todo-categories))) (setq todo-category-number *************** *** 861,869 **** "Return non-nil if STRING spans several lines." (> (todo-string-count-lines string) 1)) ! (defun todo-category-alist () ! "Generate an alist for use in `completing-read' from `todo-categories'." ! (mapcar #'list todo-categories)) ;; --------------------------------------------------------------------------- --- 849,867 ---- "Return non-nil if STRING spans several lines." (> (todo-string-count-lines string) 1)) ! (defun todo-completing-read () ! "Return a category name, with completion, for use in Todo mode." ! ;; make a copy of todo-categories in case history-delete-duplicates is ! ;; non-nil, which makes completing-read alter todo-categories ! (let* ((categories (copy-sequence todo-categories)) ! (history (cons 'todo-categories (1+ todo-category-number))) ! (default (nth todo-category-number todo-categories)) ! (category (completing-read ! (concat "Category [" default "]: ") ! todo-categories nil nil nil history default))) ! ;; restore the original value of todo-categories ! (setq todo-categories categories) ! category)) ;; --------------------------------------------------------------------------- --=-=-=-- ------------=_1233115510-16985-1--