Better handling of checkboxes with regards to [@start:x] constructs
* org.el (org-set-font-lock-defaults): Correct fontification for checkboxes found after [@start:?]. * org-list.el (org-list-at-regexp-after-bullet-p): skip any [@start:?] when looking at a regex after a bullet. * org-list.el (org-toggle-checkbox): correct insertion of checkboxes when there is already a [@start:?] in the item. * org-list.el (org-checkbox-blocked-p): properly check if there's an unchecked item before. * org-list.el (org-list-parse-list): function handles items having both a counter and a checkbox.
This commit is contained in:
parent
c444086ade
commit
4d40259e56
150
lisp/org-list.el
150
lisp/org-list.el
|
@ -322,6 +322,9 @@ the end of the nearest terminator from max."
|
|||
(and (org-at-item-p)
|
||||
(save-excursion
|
||||
(goto-char (match-end 0))
|
||||
;; Ignore counter if any
|
||||
(when (looking-at "\\(?:\\[@start:[0-9]+\\][ \t]*\\)?")
|
||||
(goto-char (match-end 0)))
|
||||
(looking-at regexp))))
|
||||
|
||||
(defun org-list-get-item-same-level (search-fun pos limit pre-move)
|
||||
|
@ -465,8 +468,7 @@ function ends."
|
|||
(defun org-at-item-p ()
|
||||
"Is point in a line starting a hand-formatted item?"
|
||||
(save-excursion
|
||||
(goto-char (point-at-bol))
|
||||
(looking-at org-item-beginning-re)))
|
||||
(beginning-of-line) (looking-at org-item-beginning-re)))
|
||||
|
||||
(defun org-at-item-bullet-p ()
|
||||
"Is point at the bullet of a plain list item?"
|
||||
|
@ -513,7 +515,8 @@ A checkbox is blocked if all of the following conditions are fulfilled:
|
|||
(condition-case nil (org-back-to-heading t)
|
||||
(error (throw 'exit nil)))
|
||||
(unless (org-entry-get nil "ORDERED") (throw 'exit nil))
|
||||
(when (org-search-forward-unenclosed "^[ \t]*[-+*0-9.)] \\[[- ]\\]" end t)
|
||||
(when (org-search-forward-unenclosed
|
||||
"^[ \t]*[-+*0-9.)]+[ \t]+\\(\\[@start:[0-9]+\\][ \t]+\\)?\\[[- ]\\]" end t)
|
||||
(org-current-line)))))))
|
||||
|
||||
;;; Navigate
|
||||
|
@ -1105,73 +1108,74 @@ is an integer, 0 means `-', 1 means `+' etc. If WHICH is
|
|||
|
||||
(defun org-toggle-checkbox (&optional toggle-presence)
|
||||
"Toggle the checkbox in the current line.
|
||||
With prefix arg TOGGLE-PRESENCE, add or remove checkboxes.
|
||||
With double prefix, set checkbox to [-].
|
||||
When there is an active region, toggle status or presence of the checkbox
|
||||
in the first line, and make every item in the region have the same
|
||||
status or presence, respectively.
|
||||
If the cursor is in a headline, apply this to all checkbox items in the
|
||||
text below the heading."
|
||||
|
||||
With prefix arg TOGGLE-PRESENCE, add or remove checkboxes. With
|
||||
double prefix, set checkbox to [-].
|
||||
|
||||
When there is an active region, toggle status or presence of the
|
||||
checkbox in the first line, and make every item in the region
|
||||
have the same status or presence, respectively.
|
||||
|
||||
If the cursor is in a headline, apply this to all checkbox items
|
||||
in the text below the heading, taking as reference the first item
|
||||
in subtree."
|
||||
(interactive "P")
|
||||
(catch 'exit
|
||||
(let (beg end status first-present first-status blocked)
|
||||
(cond
|
||||
((org-region-active-p)
|
||||
(setq beg (region-beginning) end (region-end)))
|
||||
((org-on-heading-p)
|
||||
(setq beg (point) end (save-excursion (outline-next-heading) (point))))
|
||||
((org-at-item-checkbox-p)
|
||||
(save-excursion
|
||||
(if (equal toggle-presence '(4))
|
||||
(progn
|
||||
(replace-match "" nil nil nil 1)
|
||||
(goto-char (match-beginning 0))
|
||||
(just-one-space))
|
||||
(when (setq blocked (org-checkbox-blocked-p))
|
||||
(error "Checkbox blocked because of unchecked box in line %d"
|
||||
blocked))
|
||||
(replace-match
|
||||
(cond ((equal toggle-presence '(16)) "[-]")
|
||||
((member (match-string 1) '("[ ]" "[-]")) "[X]")
|
||||
(t "[ ]"))
|
||||
t t nil 1)))
|
||||
(throw 'exit t))
|
||||
((org-at-item-p)
|
||||
;; add a checkbox if point is not at a description item
|
||||
(save-excursion
|
||||
(goto-char (match-end 0))
|
||||
(if (org-at-item-description-p)
|
||||
(error "Cannot add a checkbox in a description list")
|
||||
(insert "[ ] ")))
|
||||
(throw 'exit t))
|
||||
(t (error "Not at a checkbox or heading, and no active region")))
|
||||
(setq end (move-marker (make-marker) end))
|
||||
(save-excursion
|
||||
(goto-char beg)
|
||||
(setq first-present (org-at-item-checkbox-p)
|
||||
first-status
|
||||
(save-excursion
|
||||
(and (org-search-forward-unenclosed "[ \t]\\(\\[[ X]\\]\\)" end t)
|
||||
(equal (match-string 0) "[X]"))))
|
||||
(while (< (point) end)
|
||||
(if toggle-presence
|
||||
(cond
|
||||
((and first-present (org-at-item-checkbox-p))
|
||||
(save-excursion
|
||||
(replace-match "")
|
||||
(goto-char (match-beginning 0))
|
||||
(just-one-space)))
|
||||
((and (not first-present) (not (org-at-item-checkbox-p))
|
||||
(org-at-item-p))
|
||||
(save-excursion
|
||||
(goto-char (match-end 0))
|
||||
(insert "[ ] "))))
|
||||
(when (org-at-item-checkbox-p)
|
||||
(setq status (equal (match-string 1) "[X]"))
|
||||
(replace-match
|
||||
(if first-status "[ ]" "[X]") t t nil 1)))
|
||||
(beginning-of-line 2)))))
|
||||
(org-update-checkbox-count-maybe))
|
||||
;; Bounds is a list of type (beg end single-p) where single-p is t
|
||||
;; when `org-toggle-checkbox' is applied to a single item. Only
|
||||
;; toggles on single items will return errors.
|
||||
(let* ((bounds
|
||||
(cond
|
||||
((org-region-active-p)
|
||||
(list (region-beginning) (region-end) nil))
|
||||
((org-on-heading-p)
|
||||
;; In this case, reference line is the first item in subtree
|
||||
(let ((limit (save-excursion (outline-next-heading) (point))))
|
||||
(save-excursion
|
||||
(org-search-forward-unenclosed org-item-beginning-re limit 'move)
|
||||
(list (point) limit nil))))
|
||||
((org-at-item-p)
|
||||
(list (point-at-bol) (point-at-eol) t))
|
||||
(t (error "Not at an item or heading, and no active region"))))
|
||||
;; marker is needed because deleting checkboxes will change END
|
||||
(end (copy-marker (nth 1 bounds)))
|
||||
(single-p (nth 2 bounds))
|
||||
(ref-presence (save-excursion (goto-char (car bounds)) (org-at-item-checkbox-p)))
|
||||
(ref-status (equal (match-string 1) "[X]"))
|
||||
(act-on-item
|
||||
(lambda (ref-pres ref-stat)
|
||||
(if (equal toggle-presence '(4))
|
||||
(cond
|
||||
((and ref-pres (org-at-item-checkbox-p))
|
||||
(replace-match ""))
|
||||
((and (not ref-pres)
|
||||
(not (org-at-item-checkbox-p))
|
||||
(org-at-item-p))
|
||||
(goto-char (match-end 0))
|
||||
;; Ignore counter, if any
|
||||
(when (looking-at "\\(?:\\[@start:[0-9]+\\][ \t]*\\)?")
|
||||
(goto-char (match-end 0)))
|
||||
(let ((desc-p (and (org-at-item-description-p)
|
||||
(cdr (assq 'checkbox org-list-automatic-rules)))))
|
||||
(cond
|
||||
((and single-p desc-p)
|
||||
(error "Cannot add a checkbox in a description list"))
|
||||
((not desc-p) (insert "[ ] "))))))
|
||||
(let ((blocked (org-checkbox-blocked-p)))
|
||||
(cond
|
||||
((and blocked single-p)
|
||||
(error "Checkbox blocked because of unchecked box in line %d" blocked))
|
||||
(blocked nil)
|
||||
((org-at-item-checkbox-p)
|
||||
(replace-match
|
||||
(cond ((equal toggle-presence '(16)) "[-]")
|
||||
(ref-stat "[ ]")
|
||||
(t "[X]"))
|
||||
t t nil 1))))))))
|
||||
(save-excursion
|
||||
(while (< (point) end)
|
||||
(funcall act-on-item ref-presence ref-status)
|
||||
(org-search-forward-unenclosed org-item-beginning-re end 'move)))
|
||||
(org-update-checkbox-count-maybe)))
|
||||
|
||||
(defun org-reset-checkbox-state-subtree ()
|
||||
"Reset all checkboxes in an entry subtree."
|
||||
|
@ -1455,11 +1459,11 @@ sublevels as a list of strings."
|
|||
(nextitem (or (org-get-next-item (point) end) end))
|
||||
(item (org-trim (buffer-substring (point) (org-end-of-item-or-at-child))))
|
||||
(nextindent (if (= (point) end) 0 (org-get-indentation)))
|
||||
(item (if (string-match "^\\[\\([xX ]\\)\\]" item)
|
||||
(item (if (string-match "^\\(?:\\[@start:[0-9]+\\][ \t]+\\)?\\[\\([xX ]\\)\\]" item)
|
||||
(replace-match (if (equal (match-string 1 item) " ")
|
||||
"[CBOFF]"
|
||||
"[CBON]")
|
||||
t nil item)
|
||||
"CBOFF"
|
||||
"CBON")
|
||||
t nil item 1)
|
||||
item)))
|
||||
(push item output)
|
||||
(when (> nextindent indent1)
|
||||
|
|
|
@ -5457,7 +5457,7 @@ needs to be inserted at a specific position in the font-lock sequence.")
|
|||
'(org-do-emphasis-faces (0 nil append))
|
||||
'(org-do-emphasis-faces)))
|
||||
;; Checkboxes
|
||||
'("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(\\[[- X]\\]\\)"
|
||||
'("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\(?:[ \t]+\\[@start:[0-9]+\\]\\)?\\)[ \t]+\\(\\[[- X]\\]\\)"
|
||||
2 'org-checkbox prepend)
|
||||
(if org-provide-checkbox-statistics
|
||||
'("\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
|
||||
|
|
Loading…
Reference in New Issue