all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Mauro Aranda <maurooaranda@gmail.com>
To: Lars Ingebrigtsen <larsi@gnus.org>
Cc: Lennart Borgman <lennart.borgman@gmail.com>, 6419@debbugs.gnu.org
Subject: bug#6419: A suggestion for easier editing of lists in Custom buffers
Date: Thu, 22 Oct 2020 08:48:14 -0300	[thread overview]
Message-ID: <CABczVwe_9r9yR-9r3RzWxzvwwSu3AJmgqTt+fBzQS3QQrF6tJA@mail.gmail.com> (raw)
In-Reply-To: <87d01aij8b.fsf@gnus.org>


[-- Attachment #1.1: Type: text/plain, Size: 347 bytes --]

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Mauro Aranda <maurooaranda@gmail.com> writes:
>
>> Will try.
>
> OK, so you're sending a new version of the patch?  Then I won't apply
> the one you've already posted (which seemed clear enough to me, really).

Yes, here it is.  I fixed the typo, and tried to improve
the help-echo of the INS button.

[-- Attachment #1.2: Type: text/html, Size: 526 bytes --]

[-- Attachment #2: 0001-Allow-moving-members-of-editable-list-widget-via-del.patch --]
[-- Type: text/x-patch, Size: 6261 bytes --]

From ffbfcdc10f916ef37187ed2a6a8f3b2f0380e643 Mon Sep 17 00:00:00 2001
From: Mauro Aranda <maurooaranda@gmail.com>
Date: Wed, 21 Oct 2020 11:07:49 -0300
Subject: [PATCH] Allow moving members of editable-list widget, via
 delete+insert

Suggested by Lennart Borgman in Bug#6419.

* lisp/wid-edit.el (widget-editable-list-delete-at): Save into a new
widget property, :last-deleted, the WIDGET to be deleted.  Add
docstring.
(widget-editable-list-insert-before): If there is a recently deleted
child for the editable list, insert that one, instead of a new default
widget.  Add docstring.
(insert-button widget): Make :help-echo a function to avoid the
help-echo string become too long.
(delete-button widget): Tweak the :help-echo string, to document this
behavior.

* test/lisp/wid-edit-tests.el (widget-test-moving-editable-list-item):
Test the feature.

* etc/NEWS (Widget): Announce the feature.
---
 etc/NEWS                    |  7 +++++++
 lisp/wid-edit.el            | 32 ++++++++++++++++++++++++++++----
 test/lisp/wid-edit-tests.el | 19 +++++++++++++++++++
 3 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index f3e3d9a1b6..6e20530f6d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1166,6 +1166,13 @@ window after starting).  This variable defaults to nil.
 +++
 *** 'widget-choose' now supports menus in extended format.
 
+---
+*** The 'editable-list' widget now supports moving items up and down.
+You can now move items up and down by deleting and then reinserting
+them, using the DEL and INS buttons respectively.  This is useful in
+Custom buffers, for example, to change the order of the elements in a
+list.
+
 ** Miscellaneous
 
 ---
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index 6568cd2c8f..33c7de24bc 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -2721,7 +2721,10 @@ widget-radio-action
 (define-widget 'insert-button 'push-button
   "An insert button for the `editable-list' widget."
   :tag "INS"
-  :help-echo "Insert a new item into the list at this position."
+  :help-echo (lambda (widget)
+               (if (widget-get (widget-get widget :parent) :last-deleted)
+                   "Insert back the last deleted item from this list, at this position."
+                 "Insert a new item into the list at this position."))
   :action 'widget-insert-button-action)
 
 (defun widget-insert-button-action (widget &optional _event)
@@ -2734,7 +2737,7 @@ widget-insert-button-action
 (define-widget 'delete-button 'push-button
   "A delete button for the `editable-list' widget."
   :tag "DEL"
-  :help-echo "Delete this item from the list."
+  :help-echo "Delete this item from the list, saving it for later reinsertion."
   :action 'widget-delete-button-action)
 
 (defun widget-delete-button-action (widget &optional _event)
@@ -2824,9 +2827,17 @@ widget-editable-list-match-inline
     (cons found value)))
 
 (defun widget-editable-list-insert-before (widget before)
-  ;; Insert a new child in the list of children.
+  "Insert a new widget as a child of WIDGET.
+
+If there is a recently deleted child, the new widget is that deleted child.
+Otherwise, the new widget is the default child of WIDGET.
+
+The new widget gets inserted at the position of the BEFORE child."
   (save-excursion
     (let ((children (widget-get widget :children))
+          (last-deleted (let ((lst (widget-get widget :last-deleted)))
+                          (and lst (prog1 (pop lst)
+                                     (widget-put widget :last-deleted lst)))))
 	  (inhibit-read-only t)
 	  (inhibit-modification-hooks t))
       (cond (before
@@ -2834,7 +2845,11 @@ widget-editable-list-insert-before
 	    (t
 	     (goto-char (widget-get widget :value-pos))))
       (let ((child (widget-editable-list-entry-create
-		    widget nil nil)))
+                    widget (and last-deleted
+                                (widget-apply last-deleted
+                                              :value-to-external
+                                              (widget-get last-deleted :value)))
+                    last-deleted)))
 	(when (< (widget-get child :entry-from) (widget-get widget :from))
 	  (set-marker (widget-get widget :from)
 		      (widget-get child :entry-from)))
@@ -2847,6 +2862,15 @@ widget-editable-list-insert-before
   (widget-apply widget :notify widget))
 
 (defun widget-editable-list-delete-at (widget child)
+  "Delete the widget CHILD from the known children of widget WIDGET.
+
+Save CHILD into the :last-deleted list, so it can be inserted later."
+  ;; Save the current value of CHILD, to use if the user later inserts the
+  ;; widget.
+  (widget-put child :value (widget-apply child :value-get))
+  (let ((lst (widget-get widget :last-deleted)))
+    (push child lst)
+    (widget-put widget :last-deleted lst))
   ;; Delete child from list of children.
   (save-excursion
     (let ((buttons (copy-sequence (widget-get widget :buttons)))
diff --git a/test/lisp/wid-edit-tests.el b/test/lisp/wid-edit-tests.el
index df49ffc822..4508b68023 100644
--- a/test/lisp/wid-edit-tests.el
+++ b/test/lisp/wid-edit-tests.el
@@ -129,4 +129,23 @@ widget-test-editable-field-widget-value
       (widget-insert "And some non-widget text.")
       (should (string= (widget-apply wid :value-get) "")))))
 
+(ert-deftest widget-test-moving-editable-list-item ()
+  "Check that we can move an editable list item up or down, via delete+insert."
+  (with-temp-buffer
+    (widget-insert "Testing editable-list.\n\n")
+    (let ((lst (widget-create 'editable-list
+                              :value '("beg" "end" "middle")
+                              '(editable-field :value "unknown"))))
+      (use-local-map widget-keymap)
+      (widget-setup)
+      ;; Go to the DEL button for the 2nd element and action it.
+      (goto-char (widget-get (nth 2 (widget-get lst :buttons)) :from))
+      (widget-apply-action (widget-at))
+      ;; Go to the INS button and action it.
+      (goto-char (widget-get lst :to))
+      (widget-backward 1)
+      (widget-apply-action (widget-at))
+      ;; Check that we effectively moved the item to the last position.
+      (should (equal (widget-value lst) '("beg" "middle" "end"))))))
+
 ;;; wid-edit-tests.el ends here
-- 
2.28.0


  reply	other threads:[~2020-10-22 11:48 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-14  5:47 bug#6419: A suggestion for easier editing of lists in Custom buffers Lennart Borgman
2020-10-14 12:14 ` Mauro Aranda
2020-10-16  5:09   ` Lars Ingebrigtsen
2020-10-21 15:37     ` Mauro Aranda
2020-10-21 17:03       ` Drew Adams
2020-10-21 17:32         ` Mauro Aranda
2020-10-21 17:48           ` Drew Adams
2020-10-21 18:05             ` Mauro Aranda
2020-10-22 11:38               ` Lars Ingebrigtsen
2020-10-22 11:48                 ` Mauro Aranda [this message]
2020-10-22 11:54                   ` Lars Ingebrigtsen
2020-10-22 12:03                     ` Mauro Aranda

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CABczVwe_9r9yR-9r3RzWxzvwwSu3AJmgqTt+fBzQS3QQrF6tJA@mail.gmail.com \
    --to=maurooaranda@gmail.com \
    --cc=6419@debbugs.gnu.org \
    --cc=larsi@gnus.org \
    --cc=lennart.borgman@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.