Use "#+attr_org: :radio" before lists to enable radio buttons

* doc/org-manual.org (Checkboxes): Document the use of
"#+attr_org".

* lisp/org.el (org-ctrl-c-ctrl-c): When the list at point is
preceded by "#+attr_org: :radio" use `org-toggle-radio-button'
instead of `org-toggle-checkbox'.

* lisp/org-list.el (org-at-radio-list-p): New defsubst.
(org-toggle-checkbox): Use it.

* etc/ORG-NEWS: Document the use of "#+attr_org".
This commit is contained in:
Bastien 2020-02-12 01:51:46 +01:00
parent 561feb128d
commit 4028cc731b
4 changed files with 111 additions and 92 deletions

View File

@ -4539,12 +4539,13 @@ The following commands work with checkboxes:
Toggle checkbox status by using the checkbox of the item at point as
a radio button: when turned on, all other checkboxes on the same
level will be turned off. With a universal prefix argument, toggle
the presence of the checkbox. With double prefix argument, set it
the presence of the checkbox. With a double prefix argument, set it
to =[-]=.
#+findex: org-list-checkbox-radio-mode
{{{kdb(C-c C-c)}}} can be told to consider checkboxes as radio buttons
by calling {{{kbd(M-x org-list-checkbox-radio-mode)}}}, as minor mode.
{{{kdb(C-c C-c)}}} can be told to consider checkboxes as radio buttons by
setting =#+ATTR_ORG: :radio= right before the list or by calling
{{{kbd(M-x org-list-checkbox-radio-mode)}}} to activate this minor mode.
- {{{kbd(M-S-RET)}}} (~org-insert-todo-heading~) ::

View File

@ -54,6 +54,9 @@ If you want to occasionally toggle a checkbox as a radio button
without turning this minor mode on, you can use =<C-c C-x C-r>= to
call ~org-toggle-radio-button~.
You can also add =#+ATTR_ORG: :radio= right before the list to tell
Org to use radio buttons for this list only.
*** Looping agenda commands over headlines
~org-agenda-loop-over-headlines-in-active-region~ allows you to loop

View File

@ -2337,6 +2337,16 @@ is an integer, 0 means `-', 1 means `+' etc. If WHICH is
(org-list-struct-apply-struct struct old-struct)
(org-update-checkbox-count-maybe))))
(defsubst org-at-radio-list-p ()
"Is point in a list with radio buttons?"
(let (attr)
(save-excursion
(org-at-item-p)
(goto-char (caar (org-list-struct)))
(org-backward-element)
(setq attr (car (org-element-property :attr_org (org-element-at-point))))
(when attr (string-match-p ":radio" attr)))))
(defun org-toggle-checkbox (&optional toggle-presence)
"Toggle the checkbox in the current line.
@ -2351,6 +2361,8 @@ If point is on a headline, apply this to all checkbox items in
the text below the heading, taking as reference the first item in
subtree, ignoring planning line and any drawer following it."
(interactive "P")
(if (org-at-radio-list-p)
(org-toggle-radio-button toggle-presence)
(save-excursion
(let* (singlep
block-item
@ -2436,7 +2448,7 @@ subtree, ignoring planning line and any drawer following it."
(goto-char bottom)
(move-marker bottom nil)
(org-list-struct-apply-struct struct struct-copy)))
(move-marker lim-down nil)))
(move-marker lim-down nil))))
(org-update-checkbox-count-maybe))
(defun org-reset-checkbox-state-subtree ()

View File

@ -17171,6 +17171,7 @@ This command does many different things, depending on context:
src-block statistics-cookie table table-cell table-row
timestamp)
t))
(radio-list-p (org-at-radio-list-p))
(type (org-element-type context)))
;; For convenience: at the first line of a paragraph on the same
;; line as an item, apply function on that item instead.
@ -17217,8 +17218,9 @@ This command does many different things, depending on context:
;; unconditionally, whereas `C-u' will toggle its presence.
;; Without a universal argument, if the item has a checkbox,
;; toggle it. Otherwise repair the list.
(if (and (boundp org-list-checkbox-radio-mode)
org-list-checkbox-radio-mode)
(if (or radio-list-p
(and (boundp org-list-checkbox-radio-mode)
org-list-checkbox-radio-mode))
(org-toggle-radio-button arg)
(let* ((box (org-element-property :checkbox context))
(struct (org-element-property :structure context))
@ -17259,8 +17261,9 @@ This command does many different things, depending on context:
;; will toggle their presence according to the state of the
;; first item in the list. Without an argument, repair the
;; list.
(if (and (boundp org-list-checkbox-radio-mode)
org-list-checkbox-radio-mode)
(if (or radio-list-p
(and (boundp org-list-checkbox-radio-mode)
org-list-checkbox-radio-mode))
(org-toggle-radio-button arg)
(let* ((begin (org-element-property :contents-begin context))
(struct (org-element-property :structure context))