org-list: move error messages in interactive indent/outdent functions
* list/org-list.el (org-list-indent-item-generic): remove error messages happening before process. This belongs to interactive functions. (org-indent-item,org-indent-item-tree, org-outdent-item,org-outdent-item-tree): ensure point or region is correct before computing list structure. Return an error message otherwise.
This commit is contained in:
parent
9230df2e0d
commit
148deffd4e
185
lisp/org-list.el
185
lisp/org-list.el
|
@ -660,84 +660,76 @@ Return t if successful."
|
|||
(beginning-of-line)
|
||||
(let* ((regionp (org-region-active-p))
|
||||
(rbeg (and regionp (region-beginning)))
|
||||
(rend (and regionp (region-end))))
|
||||
(cond
|
||||
((and regionp
|
||||
(goto-char rbeg)
|
||||
(not (org-search-forward-unenclosed org-item-beginning-re rend t)))
|
||||
(error "No item in region"))
|
||||
((not (org-at-item-p))
|
||||
(error "Not at an item"))
|
||||
(t
|
||||
(let* ((top (org-list-get-top-point struct))
|
||||
(parents (org-list-struct-parent-alist struct))
|
||||
(prevs (org-list-struct-prev-alist struct))
|
||||
;; Are we going to move the whole list?
|
||||
(specialp (and (cdr (assq 'indent org-list-automatic-rules))
|
||||
(not no-subtree)
|
||||
(= top (point)))))
|
||||
;; 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 (point))
|
||||
(set-marker org-last-indent-end-marker
|
||||
(cond
|
||||
(specialp (org-list-get-bottom-point struct))
|
||||
(no-subtree (1+ (point)))
|
||||
(t (org-list-get-item-end (point) struct))))))
|
||||
(let* ((beg (marker-position org-last-indent-begin-marker))
|
||||
(end (marker-position org-last-indent-end-marker)))
|
||||
(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 (mapcar (lambda (e) (copy-alist e)) 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.
|
||||
(mapc (lambda (e)
|
||||
(let ((ind (org-list-get-ind (car e) struct)))
|
||||
(org-list-set-ind (car e) struct (+ ind offset))))
|
||||
struct)
|
||||
(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
|
||||
(org-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* ((new-parents
|
||||
(if (< arg 0)
|
||||
(org-list-struct-outdent beg end struct parents)
|
||||
(org-list-struct-indent beg end struct parents prevs))))
|
||||
(org-list-struct-fix-struct struct new-parents))
|
||||
(org-update-checkbox-count-maybe)))))))))
|
||||
(rend (and regionp (region-end)))
|
||||
(top (org-list-get-top-point struct))
|
||||
(parents (org-list-struct-parent-alist struct))
|
||||
(prevs (org-list-struct-prev-alist struct))
|
||||
;; Are we going to move the whole list?
|
||||
(specialp (and (cdr (assq 'indent org-list-automatic-rules))
|
||||
(not no-subtree)
|
||||
(= top (point)))))
|
||||
;; 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 (point))
|
||||
(set-marker org-last-indent-end-marker
|
||||
(cond
|
||||
(specialp (org-list-get-bottom-point struct))
|
||||
(no-subtree (1+ (point)))
|
||||
(t (org-list-get-item-end (point) struct))))))
|
||||
(let* ((beg (marker-position org-last-indent-begin-marker))
|
||||
(end (marker-position org-last-indent-end-marker)))
|
||||
(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 (mapcar (lambda (e) (copy-alist e)) 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.
|
||||
(mapc (lambda (e)
|
||||
(let ((ind (org-list-get-ind (car e) struct)))
|
||||
(org-list-set-ind (car e) struct (+ ind offset))))
|
||||
struct)
|
||||
(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
|
||||
(org-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* ((new-parents
|
||||
(if (< arg 0)
|
||||
(org-list-struct-outdent beg end struct parents)
|
||||
(org-list-struct-indent beg end struct parents prevs))))
|
||||
(org-list-struct-fix-struct struct new-parents))
|
||||
(org-update-checkbox-count-maybe))))))
|
||||
t)
|
||||
|
||||
;;; Predicates
|
||||
|
@ -1793,29 +1785,50 @@ Initial position of cursor is restored after the changes."
|
|||
"Outdent a local list item, but not its children.
|
||||
If a region is active, all items inside will be moved."
|
||||
(interactive)
|
||||
(let ((struct (org-list-struct)))
|
||||
(org-list-indent-item-generic -1 t struct)))
|
||||
(if (org-at-item-p)
|
||||
(let ((struct (org-list-struct)))
|
||||
(org-list-indent-item-generic -1 t struct))
|
||||
(error "Not at an item")))
|
||||
|
||||
(defun org-indent-item ()
|
||||
"Indent a local list item, but not its children.
|
||||
If a region is active, all items inside will be moved."
|
||||
(interactive)
|
||||
(let ((struct (org-list-struct)))
|
||||
(org-list-indent-item-generic 1 t struct)))
|
||||
(if (org-at-item-p)
|
||||
(let ((struct (org-list-struct)))
|
||||
(org-list-indent-item-generic 1 t struct))
|
||||
(error "Not at an item")))
|
||||
|
||||
(defun org-outdent-item-tree ()
|
||||
"Outdent a local list item including its children.
|
||||
If a region is active, all items inside will be moved."
|
||||
(interactive)
|
||||
(let ((struct (org-list-struct)))
|
||||
(org-list-indent-item-generic -1 nil struct)))
|
||||
(let ((regionp (org-region-active-p)))
|
||||
(cond
|
||||
((or (org-at-item-p)
|
||||
(and (org-region-active-p)
|
||||
(goto-char (region-beginning))
|
||||
(org-at-item-p)))
|
||||
(let ((struct (org-list-struct)))
|
||||
(org-list-indent-item-generic -1 nil struct)))
|
||||
(regionp (error "Region not starting at an item"))
|
||||
(t (error "Not at an item")))))
|
||||
|
||||
(defun org-indent-item-tree ()
|
||||
"Indent a local list item including its children.
|
||||
If a region is active, all items inside will be moved."
|
||||
(interactive)
|
||||
(let ((struct (org-list-struct)))
|
||||
(org-list-indent-item-generic 1 nil struct)))
|
||||
(interactive)
|
||||
(let ((regionp (org-region-active-p)))
|
||||
(cond
|
||||
((or (org-at-item-p)
|
||||
(and (org-region-active-p)
|
||||
(goto-char (region-beginning))
|
||||
(org-at-item-p)))
|
||||
(let ((struct (org-list-struct)))
|
||||
(org-list-indent-item-generic 1 nil struct)))
|
||||
(regionp (error "Region not starting at an item"))
|
||||
(t (error "Not at an item")))))
|
||||
|
||||
(defvar org-tab-ind-state)
|
||||
(defun org-cycle-item-indentation ()
|
||||
|
|
Loading…
Reference in New Issue