Browse Source

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.
Nicolas Goaziou 8 years ago
parent
commit
148deffd4e
1 changed files with 99 additions and 86 deletions
  1. 99 86
      lisp/org-list.el

+ 99 - 86
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 ()