Function: org-list-indent-item-generic
org-list-indent-item-generic is a byte-compiled function defined in
org-list.el.gz.
Signature
(org-list-indent-item-generic ARG NO-SUBTREE STRUCT)
Documentation
Indent a local list item including its children.
When number ARG is a negative, item will be outdented, otherwise it will be indented.
If a region is active, all items inside will be moved.
If NO-SUBTREE is non-nil, only indent the item itself, not its children.
STRUCT is the list structure.
Return t if successful.
Source Code
;; Defined in /usr/src/emacs/lisp/org/org-list.el.gz
(defun org-list-indent-item-generic (arg no-subtree struct)
"Indent a local list item including its children.
When number ARG is a negative, item will be outdented, otherwise
it will be indented.
If a region is active, all items inside will be moved.
If NO-SUBTREE is non-nil, only indent the item itself, not its
children.
STRUCT is the list structure.
Return t if successful."
(save-excursion
(let* ((regionp (org-region-active-p))
(rbeg (and regionp (region-beginning)))
(rend (and regionp (region-end)))
(top (org-list-get-top-point struct))
(parents (org-list-parents-alist struct))
(prevs (org-list-prevs-alist struct))
;; Are we going to move the whole list?
(specialp
(and (not regionp)
(= top (line-beginning-position))
(cdr (assq 'indent org-list-automatic-rules))
(if no-subtree
(user-error
"At first item: use S-M-<left/right> to move the whole list")
t))))
;; Determine begin and end points of zone to indent. If moving
;; more than one item, save them for subsequent moves.
(unless (and (memq last-command '(org-shiftmetaright org-shiftmetaleft))
(memq this-command '(org-shiftmetaright org-shiftmetaleft)))
(if regionp
(progn
(set-marker org-last-indent-begin-marker rbeg)
(set-marker org-last-indent-end-marker rend))
(set-marker org-last-indent-begin-marker (line-beginning-position))
(set-marker org-last-indent-end-marker
(cond
(specialp (org-list-get-bottom-point struct))
(no-subtree (1+ (line-beginning-position)))
(t (org-list-get-item-end (line-beginning-position) struct))))))
(let* ((beg (marker-position org-last-indent-begin-marker))
(end (marker-position org-last-indent-end-marker))
(deactivate-mark nil))
(cond
;; Special case: moving top-item with indent rule.
(specialp
(let* ((level-skip (org-level-increment))
(offset (if (< arg 0) (- level-skip) level-skip))
(top-ind (org-list-get-ind beg struct))
(old-struct (copy-tree struct)))
(if (< (+ top-ind offset) 0)
(error "Cannot outdent beyond margin")
;; Change bullet if necessary.
(when (and (= (+ top-ind offset) 0)
(string-match "\\*"
(org-list-get-bullet beg struct)))
(org-list-set-bullet beg struct
(org-list-bullet-string "-")))
;; Shift every item by OFFSET and fix bullets. Then
;; apply changes to buffer.
(pcase-dolist (`(,pos . ,_) struct)
(let ((ind (org-list-get-ind pos struct)))
(org-list-set-ind pos struct (+ ind offset))))
(org-list-struct-fix-bul struct prevs)
(org-list-struct-apply-struct struct old-struct))))
;; Forbidden move:
((and (< arg 0)
;; If only one item is moved, it mustn't have a child.
(or (and no-subtree
(not regionp)
(org-list-has-child-p beg struct))
;; If a subtree or region is moved, the last item
;; of the subtree mustn't have a child.
(let ((last-item (caar
(reverse
(cl-remove-if
(lambda (e) (>= (car e) end))
struct)))))
(org-list-has-child-p last-item struct))))
(error "Cannot outdent an item without its children"))
;; Normal shifting
(t
(let* ((old-struct (copy-tree struct))
(new-parents
(if (< arg 0)
(org-list-struct-outdent beg end struct parents)
(org-list-struct-indent beg end struct parents prevs))))
(org-list-write-struct struct new-parents old-struct))
(org-update-checkbox-count-maybe))))))
t)