Browse Source

Allow numeric values for priorities

* lisp/org.el (org-priority-highest, org-priority-default):
Allow integer.
(org-priority-get-priority-function): Tiny docstring change.
(org-priority-to-value): New defsubst.
(org--setup-collect-keywords, org-priority-regexp)
(org-priority, org-get-priority): Allow numeric values.

* doc/org-manual.org (Priorities): Illustrate the use of
numeric values for priorities.
Bastien 5 years ago
parent
commit
4f98694bf7
3 changed files with 88 additions and 31 deletions
  1. 13 1
      doc/org-manual.org
  2. 17 5
      etc/ORG-NEWS
  3. 58 25
      lisp/org.el

+ 13 - 1
doc/org-manual.org

@@ -4328,11 +4328,19 @@ like this
 By default, Org mode supports three priorities: =A=, =B=, and =C=.
 By default, Org mode supports three priorities: =A=, =B=, and =C=.
 =A= is the highest priority.  An entry without a cookie is treated as
 =A= is the highest priority.  An entry without a cookie is treated as
 equivalent if it had priority =B=.  Priorities make a difference only
 equivalent if it had priority =B=.  Priorities make a difference only
-for sorting in the agenda (see [[*Weekly/daily agenda]]); outside the
+for sorting in the agenda (see [[*Weekly/daily agenda]]).  Outside the
 agenda, they have no inherent meaning to Org mode.  The cookies are
 agenda, they have no inherent meaning to Org mode.  The cookies are
 displayed with the face defined by the variable ~org-priority-faces~,
 displayed with the face defined by the variable ~org-priority-faces~,
 which can be customized.
 which can be customized.
 
 
+You can also use numeric values for priorities, such as
+
+: *** TODO [#1] Write letter to Sam Fortune
+
+When using numeric priorities, you need to set ~org-priority-highest~,
+~org-priority-lowest~ and ~org-priority-default~ to integers, which
+must all be strictly inferior to 65.
+
 Priorities can be attached to any outline node; they do not need to be
 Priorities can be attached to any outline node; they do not need to be
 TODO items.
 TODO items.
 
 
@@ -4372,6 +4380,10 @@ highest priority is earlier in the alphabet than the lowest priority):
 #+cindex: @samp{PRIORITIES}, keyword
 #+cindex: @samp{PRIORITIES}, keyword
 : #+PRIORITIES: A C B
 : #+PRIORITIES: A C B
 
 
+Or, using numeric values:
+
+: #+PRIORITIES: 1 10 5
+
 ** Breaking Down Tasks into Subtasks
 ** Breaking Down Tasks into Subtasks
 :PROPERTIES:
 :PROPERTIES:
 :DESCRIPTION: Splitting a task into manageable pieces.
 :DESCRIPTION: Splitting a task into manageable pieces.

+ 17 - 5
etc/ORG-NEWS

@@ -13,6 +13,18 @@ Please send Org bug reports to mailto:emacs-orgmode@gnu.org.
 * Version 9.4 (not yet released)
 * Version 9.4 (not yet released)
 ** New features
 ** New features
 
 
+*** Numeric priorities are now allowed (up to 65)
+
+You can now set ~org-priority-highest/lowest/default~ to integers to
+use numeric priorities globally or set, for example
+
+#+PRIORITIES: 1 10 5
+
+to define a buffer-local range and default for priorities.  Priority
+commands should work as usual.  You cannot use numbers superior to 64
+for numeric priorities, as it would clash with priorities like [#A]
+where the "A" is internally converted to its numeric value of 65.
+
 *** New minor mode ~org-table-electric-header-mode~
 *** New minor mode ~org-table-electric-header-mode~
 
 
 Turn on the display of the first data row of the table at point in the
 Turn on the display of the first data row of the table at point in the
@@ -37,11 +49,6 @@ things in a property drawer before the first headline will make them
 A new `:tree-type month' option was added to org-capture-templates to
 A new `:tree-type month' option was added to org-capture-templates to
 group new datetime entries by month.
 group new datetime entries by month.
 
 
-*** New header argument to pass Java command line arguments
-
-Babel Java blocks recognize header argument =:cmdargs= and pass its
-value in call to =java=.
-
 *** Refinement in window behavior on exiting Org source buffer
 *** Refinement in window behavior on exiting Org source buffer
 
 
 After editing a source block, Org will restore the window layout when
 After editing a source block, Org will restore the window layout when
@@ -58,6 +65,11 @@ buffers are displayed by modifying ~display-buffer-alist~ or
 
 
 This option will add a timeout to notifications.
 This option will add a timeout to notifications.
 
 
+*** Babel: new header argument to pass Java command line arguments
+
+Babel Java blocks recognize header argument =:cmdargs= and pass its
+value in call to =java=.
+
 ** New commands
 ** New commands
 *** ~org-table-electric-header-mode~
 *** ~org-table-electric-header-mode~
 
 

+ 58 - 25
lisp/org.el

@@ -2566,17 +2566,23 @@ set a priority."
 
 
 (defvaralias 'org-highest-priority 'org-priority-highest)
 (defvaralias 'org-highest-priority 'org-priority-highest)
 (defcustom org-priority-highest ?A
 (defcustom org-priority-highest ?A
-  "The highest priority of TODO items.  A character like ?A, ?B etc.
-Must have a smaller ASCII number than `org-priority-lowest'."
+  "The highest priority of TODO items.
+A character like ?A, ?B, etc., or a numeric value like 1, 2, etc.
+Must be smaller than `org-priority-lowest'."
   :group 'org-priorities
   :group 'org-priorities
-  :type 'character)
+  :type '(choice
+	  (character :tag "Character")
+	  (integer :tag "Integer (< 65)")))
 
 
 (defvaralias 'org-lowest-priority 'org-priority-lowest)
 (defvaralias 'org-lowest-priority 'org-priority-lowest)
 (defcustom org-priority-lowest ?C
 (defcustom org-priority-lowest ?C
-  "The lowest priority of TODO items.  A character like ?A, ?B etc.
-Must have a larger ASCII number than `org-priority-highest'."
+  "The lowest priority of TODO items.
+A character like ?A, ?B, etc., or a numeric value like 1, 2, etc.
+Must be higher than `org-priority-highest'."
   :group 'org-priorities
   :group 'org-priorities
-  :type 'character)
+  :type '(choice
+	  (character :tag "Character")
+	  (integer :tag "Integer (< 65)")))
 
 
 (defvaralias 'org-default-priority 'org-priority-default)
 (defvaralias 'org-default-priority 'org-priority-default)
 (defcustom org-priority-default ?B
 (defcustom org-priority-default ?B
@@ -2586,11 +2592,13 @@ When starting to cycle on an empty priority the first step in the cycle
 depends on `org-priority-start-cycle-with-default'.  The resulting first
 depends on `org-priority-start-cycle-with-default'.  The resulting first
 step priority must not exceed the range from `org-priority-highest' to
 step priority must not exceed the range from `org-priority-highest' to
 `org-priority-lowest' which means that `org-priority-default' has to be
 `org-priority-lowest' which means that `org-priority-default' has to be
-in this range exclusive or inclusive the range boundaries.  Else the
-first step refuses to set the default and the second will fall back
-to (depending on the command used) the highest or lowest priority."
+in this range exclusive or inclusive to the range boundaries.  Else the
+first step refuses to set the default and the second will fall back on
+(depending on the command used) the highest or lowest priority."
   :group 'org-priorities
   :group 'org-priorities
-  :type 'character)
+  :type '(choice
+	  (character :tag "Character")
+	  (integer :tag "Integer (< 65)")))
 
 
 (defcustom org-priority-start-cycle-with-default t
 (defcustom org-priority-start-cycle-with-default t
   "Non-nil means start with default priority when starting to cycle.
   "Non-nil means start with default priority when starting to cycle.
@@ -2603,7 +2611,7 @@ See also `org-priority-default'."
 (defvaralias 'org-get-priority-function 'org-priority-get-priority-function)
 (defvaralias 'org-get-priority-function 'org-priority-get-priority-function)
 (defcustom org-priority-get-priority-function nil
 (defcustom org-priority-get-priority-function nil
   "Function to extract the priority from a string.
   "Function to extract the priority from a string.
-The string is normally the headline.  If this is nil Org computes the
+The string is normally the headline.  If this is nil Org, computes the
 priority from the priority cookie like [#A] in the headline.  It returns
 priority from the priority cookie like [#A] in the headline.  It returns
 an integer, increasing by 1000 for each priority level.
 an integer, increasing by 1000 for each priority level.
 The user can set a different function here, which should take a string
 The user can set a different function here, which should take a string
@@ -4502,6 +4510,13 @@ related expressions."
 		      "[ \t]*$"))
 		      "[ \t]*$"))
 	(org-compute-latex-and-related-regexp)))))
 	(org-compute-latex-and-related-regexp)))))
 
 
+(defsubst org-priority-to-value (s)
+  "Convert priority string S to its numeric value."
+  (or (save-match-data
+	(and (string-match "\\([0-9]+\\)" s)
+	     (string-to-number (match-string 1 s))))
+      (string-to-char s)))
+
 (defun org--setup-collect-keywords (regexp &optional files alist)
 (defun org--setup-collect-keywords (regexp &optional files alist)
   "Return setup keywords values as an alist.
   "Return setup keywords values as an alist.
 
 
@@ -4561,8 +4576,11 @@ Return value contains the following keys: `archive', `category',
 	      ((equal key "PRIORITIES")
 	      ((equal key "PRIORITIES")
 	       (push (cons 'priorities
 	       (push (cons 'priorities
 			   (let ((prio (split-string value)))
 			   (let ((prio (split-string value)))
-			     (if (< (length prio) 3) '(?A ?C ?B)
-			       (mapcar #'string-to-char prio))))
+			     (if (< (length prio) 3)
+				 (list org-priority-highest
+				       org-priority-lowest
+				       org-priority-default)
+			       (mapcar #'org-priority-to-value prio))))
 		     alist))
 		     alist))
 	      ((equal key "PROPERTY")
 	      ((equal key "PROPERTY")
 	       (when (string-match "\\(\\S-+\\)[ \t]+\\(.*\\)" value)
 	       (when (string-match "\\(\\S-+\\)[ \t]+\\(.*\\)" value)
@@ -11631,7 +11649,8 @@ from the `before-change-functions' in the current buffer."
 ;;;; Priorities
 ;;;; Priorities
 
 
 (defvar org-priority-regexp ".*?\\(\\[#\\([A-Z0-9]+\\)\\] ?\\)"
 (defvar org-priority-regexp ".*?\\(\\[#\\([A-Z0-9]+\\)\\] ?\\)"
-  "Regular expression matching the priority indicator.")
+  "Regular expression matching the priority indicator.
+A priority indicator can be e.g. [#A] or [#1].")
 
 
 (defun org-priority-up ()
 (defun org-priority-up ()
   "Increase the priority of the current item."
   "Increase the priority of the current item."
@@ -11661,12 +11680,14 @@ or a character."
     (unless org-priority-enable-commands
     (unless org-priority-enable-commands
       (user-error "Priority commands are disabled"))
       (user-error "Priority commands are disabled"))
     (setq action (or action 'set))
     (setq action (or action 'set))
-    (let (current new news have remove)
+    (let ((nump (< org-priority-lowest 65))
+	  current new news have remove)
       (save-excursion
       (save-excursion
 	(org-back-to-heading t)
 	(org-back-to-heading t)
 	(when (looking-at org-priority-regexp)
 	(when (looking-at org-priority-regexp)
-	  (setq current (string-to-char (match-string 2))
-		have t))
+	  (let ((ms (match-string 2)))
+	    (setq current (org-priority-to-value ms)
+		  have t)))
 	(cond
 	(cond
 	 ((eq action 'remove)
 	 ((eq action 'remove)
 	  (setq remove t new ?\ ))
 	  (setq remove t new ?\ ))
@@ -11674,17 +11695,27 @@ or a character."
 	      (integerp action))
 	      (integerp action))
 	  (if (not (eq action 'set))
 	  (if (not (eq action 'set))
 	      (setq new action)
 	      (setq new action)
-	    (message "Priority %c-%c, SPC to remove: "
-		     org-priority-highest org-priority-lowest)
-	    (save-match-data
-	      (setq new (read-char-exclusive))))
+	    (setq
+	     new
+	     (if nump
+		 (string-to-number
+		  (read-string (format "Priority %s-%s, SPC to remove: "
+				       (number-to-string org-priority-highest)
+				       (number-to-string org-priority-lowest))))
+	       (progn (message "Priority %c-%c, SPC to remove: "
+				 org-priority-highest org-priority-lowest)
+			(save-match-data
+			  (setq new (read-char-exclusive)))))))
 	  (when (and (= (upcase org-priority-highest) org-priority-highest)
 	  (when (and (= (upcase org-priority-highest) org-priority-highest)
 		     (= (upcase org-priority-lowest) org-priority-lowest))
 		     (= (upcase org-priority-lowest) org-priority-lowest))
 	    (setq new (upcase new)))
 	    (setq new (upcase new)))
 	  (cond ((equal new ?\s) (setq remove t))
 	  (cond ((equal new ?\s) (setq remove t))
 		((or (< (upcase new) org-priority-highest) (> (upcase new) org-priority-lowest))
 		((or (< (upcase new) org-priority-highest) (> (upcase new) org-priority-lowest))
-		 (user-error "Priority must be between `%c' and `%c'"
-			     org-priority-highest org-priority-lowest))))
+		 (user-error
+		  (if nump
+		      "Priority must be between `%s' and `%s'"
+		    "Priority must be between `%c' and `%c'")
+		  org-priority-highest org-priority-lowest))))
 	 ((eq action 'up)
 	 ((eq action 'up)
 	  (setq new (if have
 	  (setq new (if have
 			(1- current)  ; normal cycling
 			(1- current)  ; normal cycling
@@ -11716,7 +11747,9 @@ or a character."
 	    ;; normal cycling: `new' is beyond highest/lowest priority
 	    ;; normal cycling: `new' is beyond highest/lowest priority
 	    ;; and is wrapped around to the empty priority
 	    ;; and is wrapped around to the empty priority
 	    (setq remove t)))
 	    (setq remove t)))
-	(setq news (format "%c" new))
+	;; Numerical priorities are limited to 64, beyond that number,
+	;; assume the priority cookie is a character.
+	(setq news (if (> new 64) (format "%c" new) (format "%s" new)))
 	(if have
 	(if have
 	    (if remove
 	    (if remove
 		(replace-match "" t t nil 1)
 		(replace-match "" t t nil 1)
@@ -11758,7 +11791,7 @@ and by additional input from the age of a schedules or deadline entry."
       (if (not (string-match org-priority-regexp s))
       (if (not (string-match org-priority-regexp s))
 	  (* 1000 (- org-priority-lowest org-priority-default))
 	  (* 1000 (- org-priority-lowest org-priority-default))
 	(* 1000 (- org-priority-lowest
 	(* 1000 (- org-priority-lowest
-		   (string-to-char (match-string 2 s))))))))
+		   (org-priority-to-value (match-string 2 s))))))))
 
 
 ;;;; Tags
 ;;;; Tags