Browse Source

org-list: Fix list type with mixed constructs

* lisp/org-list.el (org-list-automatic-rules): Remove `bullet' rule,
  which is now hard-coded.
(org-cycle-list-bullet): Hard code `bullet' rule.
(org-list-get-list-type): Make sure a list with numbered bullets
cannot have `descriptive' type.
* testing/lisp/test-org-list.el: Add tests.
Nicolas Goaziou 7 years ago
parent
commit
50a434bb9f
2 changed files with 112 additions and 14 deletions
  1. 7 14
      lisp/org-list.el
  2. 105 0
      testing/lisp/test-org-list.el

+ 7 - 14
lisp/org-list.el

@@ -236,8 +236,7 @@ Otherwise, two of them will be necessary."
   :group 'org-plain-lists
   :type 'boolean)
 
-(defcustom org-list-automatic-rules '((bullet . t)
-				      (checkbox . t)
+(defcustom org-list-automatic-rules '((checkbox . t)
 				      (indent . t))
   "Non-nil means apply set of rules when acting on lists.
 By default, automatic actions are taken when using
@@ -247,9 +246,6 @@ By default, automatic actions are taken when using
  \\[org-insert-todo-heading].  You can disable individually these
  rules by setting them to nil.  Valid rules are:
 
-bullet    when non-nil, cycling bullet do not allow lists at
-          column 0 to have * as a bullet and descriptions lists
-          to be numbered.
 checkbox  when non-nil, checkbox statistics is updated each time
           you either insert a new checkbox or toggle a checkbox.
 indent    when non-nil, indenting or outdenting list top-item
@@ -261,7 +257,6 @@ indent    when non-nil, indenting or outdenting list top-item
   :type '(alist :tag "Sets of rules"
 		:key-type
 		(choice
-		 (const :tag "Bullet" bullet)
 		 (const :tag "Checkbox" checkbox)
 		 (const :tag "Indent" indent))
 		:value-type
@@ -1013,8 +1008,8 @@ Possible types are `descriptive', `ordered' and `unordered'.  The
 type is determined by the first item of the list."
   (let ((first (org-list-get-list-begin item struct prevs)))
     (cond
-     ((org-list-get-tag first struct) 'descriptive)
      ((string-match "[[:alnum:]]" (org-list-get-bullet first struct)) 'ordered)
+     ((org-list-get-tag first struct) 'descriptive)
      (t 'unordered))))
 
 (defun org-list-get-item-number (item struct prevs parents)
@@ -2228,7 +2223,6 @@ is an integer, 0 means `-', 1 means `+' etc.  If WHICH is
            (prevs (org-list-prevs-alist struct))
            (list-beg (org-list-get-first-item (point) struct prevs))
            (bullet (org-list-get-bullet list-beg struct))
-	   (bullet-rule-p (cdr (assq 'bullet org-list-automatic-rules)))
 	   (alpha-p (org-list-use-alpha-bul-p list-beg struct prevs))
 	   (case-fold-search nil)
 	   (current (cond
@@ -2243,22 +2237,21 @@ is an integer, 0 means `-', 1 means `+' etc.  If WHICH is
 	   (bullet-list
 	    (append '("-" "+" )
 		    ;; *-bullets are not allowed at column 0.
-		    (unless (and bullet-rule-p
-				 (looking-at "\\S-")) '("*"))
+		    (unless (looking-at "\\S-") '("*"))
 		    ;; Description items cannot be numbered.
 		    (unless (or (eq org-plain-list-ordered-item-terminator ?\))
-				(and bullet-rule-p (org-at-item-description-p)))
+				(org-at-item-description-p))
 		      '("1."))
 		    (unless (or (eq org-plain-list-ordered-item-terminator ?.)
-				(and bullet-rule-p (org-at-item-description-p)))
+				(org-at-item-description-p))
 		      '("1)"))
 		    (unless (or (not alpha-p)
 				(eq org-plain-list-ordered-item-terminator ?\))
-				(and bullet-rule-p (org-at-item-description-p)))
+				(org-at-item-description-p))
 		      '("a." "A."))
 		    (unless (or (not alpha-p)
 				(eq org-plain-list-ordered-item-terminator ?.)
-				(and bullet-rule-p (org-at-item-description-p)))
+				(org-at-item-description-p))
 		      '("a)" "A)"))))
 	   (len (length bullet-list))
 	   (item-index (- len (length (member current bullet-list))))

+ 105 - 0
testing/lisp/test-org-list.el

@@ -113,6 +113,111 @@
 	(org-previous-item)
 	(should (looking-at "  - item 1.3"))))))
 
+(ert-deftest test-org-list/cycle-bullet ()
+  "Test `org-cycle-list-bullet' specifications."
+  ;; Error when not at an item.
+  (should-error
+   (org-test-with-temp-text "Paragraph"
+     (org-cycle-list-bullet)))
+  ;; Cycle through "-", "+", "*", "1.", "1)".
+  (org-test-with-temp-text "  - item"
+    (org-cycle-list-bullet)
+    (should (looking-at "[ \t]+\\+"))
+    (org-cycle-list-bullet)
+    (should (looking-at "[ \t]+\\*"))
+    (let ((org-plain-list-ordered-item-terminator t))
+      (org-cycle-list-bullet))
+    (should (looking-at "[ \t]+1\\."))
+    (let ((org-plain-list-ordered-item-terminator t))
+      (org-cycle-list-bullet))
+    (should (looking-at "[ \t]+1)")))
+  ;; Argument is a valid bullet: cycle to that bullet directly.
+  (should
+   (equal "1. item"
+	  (org-test-with-temp-text "- item"
+	    (let ((org-plain-list-ordered-item-terminator t))
+	      (org-cycle-list-bullet "1.")
+	      (buffer-string)))))
+  ;; Argument is an integer N: cycle to the Nth allowed bullet.
+  (should
+   (equal "+ item"
+	  (org-test-with-temp-text "1. item"
+	    (let ((org-plain-list-ordered-item-terminator t))
+	      (org-cycle-list-bullet 1)
+	      (buffer-string)))))
+  ;; Argument is `previous': cycle backwards.
+  (should
+   (equal "- item"
+	  (org-test-with-temp-text "+ item"
+	    (let ((org-plain-list-ordered-item-terminator t))
+	      (org-cycle-list-bullet 'previous)
+	      (buffer-string)))))
+  ;; Do not cycle to "*" bullets when item is at column 0.
+  (should
+   (equal "1. item"
+	  (org-test-with-temp-text "+ item"
+	    (let ((org-plain-list-ordered-item-terminator t))
+	      (org-cycle-list-bullet)
+	      (buffer-string)))))
+  ;; Do not cycle to numbered bullets in a description list.
+  (should-not
+   (equal "1. tag :: item"
+	  (org-test-with-temp-text "+ tag :: item"
+	    (let ((org-plain-list-ordered-item-terminator t))
+	      (org-cycle-list-bullet)
+	      (buffer-string)))))
+  ;; Do not cycle to ordered item terminators if they are not allowed
+  ;; in `org-plain-list-ordered-item-terminator'.
+  (should
+   (equal "  1) item"
+	  (org-test-with-temp-text "  * item"
+	    (let ((org-plain-list-ordered-item-terminator 41))
+	      (org-cycle-list-bullet)
+	      (buffer-string)))))
+  ;; When `org-alphabetical-lists' is non-nil, cycle to alpha bullets.
+  (should
+   (equal "a. item"
+	  (org-test-with-temp-text "1) item"
+	    (let ((org-plain-list-ordered-item-terminator t)
+		  (org-alphabetical-lists t))
+	      (org-cycle-list-bullet)
+	      (buffer-string)))))
+  ;; Do not cycle to alpha bullets when list has more than 26
+  ;; elements.
+  (should-not
+   (equal "a. item 1"
+	  (org-test-with-temp-text "1) item 1
+2) item 2
+3) item 3
+4) item 4
+5) item 5
+6) item 6
+7) item 7
+8) item 8
+9) item 9
+10) item 10
+11) item 11
+12) item 12
+13) item 13
+14) item 14
+15) item 15
+16) item 16
+17) item 17
+18) item 18
+19) item 19
+20) item 20
+21) item 21
+22) item 22
+23) item 23
+24) item 24
+25) item 25
+26) item 26
+27) item 27"
+	    (let ((org-plain-list-ordered-item-terminator t)
+		  (org-alphabetical-lists t))
+	      (org-cycle-list-bullet)
+	      (buffer-substring (point) (line-end-position)))))))
+
 (ert-deftest test-org-list/indent-item ()
   "Test `org-indent-item' specifications."
   ;; 1. Error when not at an item.