emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* inherit priority
@ 2017-12-31 18:14 Jesse Johnson
  2018-01-03 21:41 ` Nicolas Goaziou
  0 siblings, 1 reply; 15+ messages in thread
From: Jesse Johnson @ 2017-12-31 18:14 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 589 bytes --]

Hi all,

I want child org items to inherit priority from their parent.

I tried setting |org-use-property-inheritance '("PRIORITY")|, but it did 
not have any apparent effect.

Use case: I often have high priority projects whose tasks are mostly 
equally important. I don't want to waste time setting priorities for 
each individual child task unless it differs from the parent (e.g., an 
optional subtask may have lower priority).

I realize this has been brought up a few times over the years, but I 
couldn't find any recent info on how this is doable with stock org.

Gracias,

Jesse


[-- Attachment #2: Type: text/html, Size: 958 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2017-12-31 18:14 inherit priority Jesse Johnson
@ 2018-01-03 21:41 ` Nicolas Goaziou
  2018-01-04  4:04   ` Jesse Johnson
  0 siblings, 1 reply; 15+ messages in thread
From: Nicolas Goaziou @ 2018-01-03 21:41 UTC (permalink / raw)
  To: Jesse Johnson; +Cc: emacs-orgmode

Hello,

Jesse Johnson <bbuknight@gmail.com> writes:

> I want child org items to inherit priority from their parent.
>
> I tried setting |org-use-property-inheritance '("PRIORITY")|, but it
> did not have any apparent effect.

What did you try exactly, i.e., how could you show an ECM demonstrating
the issue?

Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2018-01-03 21:41 ` Nicolas Goaziou
@ 2018-01-04  4:04   ` Jesse Johnson
  2018-01-04  8:15     ` Nicolas Goaziou
  0 siblings, 1 reply; 15+ messages in thread
From: Jesse Johnson @ 2018-01-04  4:04 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode

Hi!

I don't know what an ECM is in this context, but I assume you mean a 
minimal reproducible case.

1. Set |org-use-property-inheritance '("PRIORITY")|

2. Create a new org file with this content:

* [#A] parent
** child A
** child B

3. View org-columns (C-c C-x C-c in my setup)

4. Note that the children have priority B, while parent has priority A.

For my use case I want org agenda to recognize that priority is being 
inherited for purpose of filtering and sorting.

On 01/03/2018 01:41 PM, Nicolas Goaziou wrote:
> Hello,
>
> Jesse Johnson <bbuknight@gmail.com> writes:
>
>> I want child org items to inherit priority from their parent.
>>
>> I tried setting |org-use-property-inheritance '("PRIORITY")|, but it
>> did not have any apparent effect.
> What did you try exactly, i.e., how could you show an ECM demonstrating
> the issue?
>
> Regards,
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2018-01-04  4:04   ` Jesse Johnson
@ 2018-01-04  8:15     ` Nicolas Goaziou
  2018-01-05  4:00       ` Jesse Johnson
  0 siblings, 1 reply; 15+ messages in thread
From: Nicolas Goaziou @ 2018-01-04  8:15 UTC (permalink / raw)
  To: Jesse Johnson; +Cc: emacs-orgmode

Hello,

Jesse Johnson <bbuknight@gmail.com> writes:

> 1. Set |org-use-property-inheritance '("PRIORITY")|
>
> 2. Create a new org file with this content:
>
> * [#A] parent
> ** child A
> ** child B
>
> 3. View org-columns (C-c C-x C-c in my setup)
>
> 4. Note that the children have priority B, while parent has priority
> A.

Oh yes, I realize now. PRIORITY is a special property:

  (info "(org) Special properties")

They follow their own inheritance rules -- in this case, none.

Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2018-01-04  8:15     ` Nicolas Goaziou
@ 2018-01-05  4:00       ` Jesse Johnson
  2018-01-05  7:24         ` Nicolas Goaziou
  2018-04-26 23:34         ` Bastien
  0 siblings, 2 replies; 15+ messages in thread
From: Jesse Johnson @ 2018-01-05  4:00 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode

There have been several requests for priority inheritance over the 
years. If it can't currently be done, I am willing to take a look at 
implementing it.


On 01/04/2018 12:15 AM, Nicolas Goaziou wrote:
> Hello,
>
> Jesse Johnson <bbuknight@gmail.com> writes:
>
>> 1. Set |org-use-property-inheritance '("PRIORITY")|
>>
>> 2. Create a new org file with this content:
>>
>> * [#A] parent
>> ** child A
>> ** child B
>>
>> 3. View org-columns (C-c C-x C-c in my setup)
>>
>> 4. Note that the children have priority B, while parent has priority
>> A.
> Oh yes, I realize now. PRIORITY is a special property:
>
>    (info "(org) Special properties")
>
> They follow their own inheritance rules -- in this case, none.
>
> Regards,
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2018-01-05  4:00       ` Jesse Johnson
@ 2018-01-05  7:24         ` Nicolas Goaziou
  2018-01-07 22:47           ` Jesse Johnson
  2018-04-26 23:34         ` Bastien
  1 sibling, 1 reply; 15+ messages in thread
From: Nicolas Goaziou @ 2018-01-05  7:24 UTC (permalink / raw)
  To: Jesse Johnson; +Cc: emacs-orgmode

Hello,

Jesse Johnson <bbuknight@gmail.com> writes:

> There have been several requests for priority inheritance over the
> years.

That doesn't ring a bell.

> If it can't currently be done,

I don't think it can, atm.

> I am willing to take a look at implementing it.

OK! 

IMO, there should be a global variable to allow priority inheritance
(default off).

Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2018-01-05  7:24         ` Nicolas Goaziou
@ 2018-01-07 22:47           ` Jesse Johnson
  2018-01-08 13:16             ` Nicolas Goaziou
  0 siblings, 1 reply; 15+ messages in thread
From: Jesse Johnson @ 2018-01-07 22:47 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode

Hi,

I am trying to determine the functions I need to add / update to respect 
priority inheritance.

I see that org-show-priority would need to be updated, and likely a new 
function, say org-get-priority-with-inheritance, should supplement 
org-get-priority.

However, I can't figure out where org-colview is getting the priority 
from. It seems to be parsing and validating the priority prior to 
display since it regresses to org-default-priority if I input 
[#NONSENSE] priorities.

I also don't know where sorting is considering priority.

Help with pointing me in the right direction for either of those would 
be much appreciated! Also let me know if other things touching priority 
need updating for inheritance.

Jesse


On 01/04/2018 11:24 PM, Nicolas Goaziou wrote:
> Hello,
>
> Jesse Johnson <bbuknight@gmail.com> writes:
>
>> There have been several requests for priority inheritance over the
>> years.
> That doesn't ring a bell.
>
>> If it can't currently be done,
> I don't think it can, atm.
>
>> I am willing to take a look at implementing it.
> OK!
>
> IMO, there should be a global variable to allow priority inheritance
> (default off).
>
> Regards,
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2018-01-07 22:47           ` Jesse Johnson
@ 2018-01-08 13:16             ` Nicolas Goaziou
  0 siblings, 0 replies; 15+ messages in thread
From: Nicolas Goaziou @ 2018-01-08 13:16 UTC (permalink / raw)
  To: Jesse Johnson; +Cc: emacs-orgmode

Hello,

Jesse Johnson <bbuknight@gmail.com> writes:

> I am trying to determine the functions I need to add / update to
> respect priority inheritance.
>
> I see that org-show-priority would need to be updated,

Correct, but that would be a minor change.

> and likely
> a new function, say org-get-priority-with-inheritance, should
> supplement org-get-priority.

I think you need to change `org-get-priority' signature. You can remove
the string argument and possibly add an optional argument: a buffer
position. It should handle inheritance without any additional function,
if a global variable, e.g., `org-priority-use-inheritance' is non-nil.

Note that you can already achieve inheritance by setting
`org-get-priority-function' to a function that searches priority cookies
among ancestors of the current headline.

> However, I can't figure out where org-colview is getting the priority
> from.

From `org-entry-get' -> `org-entry-properties'.

I don't think there's any change involved in "org-colview.el".

> I also don't know where sorting is considering priority.
>
> Help with pointing me in the right direction for either of those would
> be much appreciated! Also let me know if other things touching
> priority need updating for inheritance.

You should start with `org-get-priority'. Most things are going to work
once it is updated.

Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2018-01-05  4:00       ` Jesse Johnson
  2018-01-05  7:24         ` Nicolas Goaziou
@ 2018-04-26 23:34         ` Bastien
  2018-04-27  1:34           ` Jesse Johnson
  1 sibling, 1 reply; 15+ messages in thread
From: Bastien @ 2018-04-26 23:34 UTC (permalink / raw)
  To: Jesse Johnson; +Cc: emacs-orgmode, Nicolas Goaziou

Hi Jesse,

Jesse Johnson <bbuknight@gmail.com> writes:

> There have been several requests for priority inheritance over the
> years. If it can't currently be done, I am willing to take a look at
> implementing it.

Did you make progress on this?

FWIW I'm not convinced it is worth implementing priority inheritance,
and like Nicolas, I don't remember any request for this (but my memory
can be wrong here).

Best,

-- 
 Bastien

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2018-04-26 23:34         ` Bastien
@ 2018-04-27  1:34           ` Jesse Johnson
  2018-04-27  1:59             ` Bastien
  0 siblings, 1 reply; 15+ messages in thread
From: Jesse Johnson @ 2018-04-27  1:34 UTC (permalink / raw)
  To: Bastien; +Cc: emacs-orgmode, Nicolas Goaziou



On 04/26/2018 04:34 PM, Bastien wrote:
>> There have been several requests for priority inheritance over the
>> years. If it can't currently be done, I am willing to take a look at
>> implementing it.
> Did you make progress on this?

Crazy timing! I've been testing my implementation for a few months, made 
some big adjustments a couple weeks ago and plan to submit a patch this 
weekend.

> FWIW I'm not convinced it is worth implementing priority inheritance,
> and like Nicolas, I don't remember any request for this (but my memory
> can be wrong here).

Well, I asked for it, so there's at least one person asked for it! Very 
tedious busy-body work setting priority on dozens of subtasks when they 
all share the same priority as their parent task. Will save me hours of 
effort over the course of a year. I'm surprised it wasn't already 
implemented.

FWIW, I found a few requests for this feature while searching for a 
solution. However I implemented it because it's useful to me, not 
because anyone asked me to.

Jesse

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2018-04-27  1:34           ` Jesse Johnson
@ 2018-04-27  1:59             ` Bastien
  2018-07-08  1:55               ` Jesse Johnson
  0 siblings, 1 reply; 15+ messages in thread
From: Bastien @ 2018-04-27  1:59 UTC (permalink / raw)
  To: Jesse Johnson; +Cc: emacs-orgmode, Nicolas Goaziou

Hi Jesse,

Jesse Johnson <bbuknight@gmail.com> writes:

> Crazy timing! I've been testing my implementation for a few months,
> made some big adjustments a couple weeks ago and plan to submit a
> patch this weekend.

Nice, thanks in advance - also, when it comes to inheritance, we can
hit performance issues.  Let's make sure a new feature in this area
has no impact on the speed of, e.g., the agenda generation.

M-x profiler-start RET
M-x elp-instrument-function RET

are your friends!

-- 
 Bastien

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2018-04-27  1:59             ` Bastien
@ 2018-07-08  1:55               ` Jesse Johnson
  2018-07-09  8:22                 ` Nicolas Goaziou
  0 siblings, 1 reply; 15+ messages in thread
From: Jesse Johnson @ 2018-07-08  1:55 UTC (permalink / raw)
  To: Bastien; +Cc: emacs-orgmode, Nicolas Goaziou

Hi all,

Here is my branch adding priority inheritance.

remote: https://code.orgmode.org/holocronweaver/org-mode.git

branch: inherit-priority-squashed

I rebased upon the latest master, everything still seems to work. Sorry 
for the long delay in release.

Please test and critique.

Thanks!

Jesse

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2018-07-08  1:55               ` Jesse Johnson
@ 2018-07-09  8:22                 ` Nicolas Goaziou
  2018-07-10  5:03                   ` Jesse Johnson
  0 siblings, 1 reply; 15+ messages in thread
From: Nicolas Goaziou @ 2018-07-09  8:22 UTC (permalink / raw)
  To: Jesse Johnson; +Cc: Bastien, emacs-orgmode

Hello,

Jesse Johnson <holocronweaver@gmail.com> writes:

> Here is my branch adding priority inheritance.
>
> remote: https://code.orgmode.org/holocronweaver/org-mode.git

It looks good. Could you send it on this ML as a patch so I can comment
it more conveniently?

Thank you.

Regards,

-- 
Nicolas Goaziou                                                0x80A93738

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2018-07-09  8:22                 ` Nicolas Goaziou
@ 2018-07-10  5:03                   ` Jesse Johnson
  2018-07-18 12:54                     ` Nicolas Goaziou
  0 siblings, 1 reply; 15+ messages in thread
From: Jesse Johnson @ 2018-07-10  5:03 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Bastien, emacs-orgmode

Hi Nicolas,

On 07/09/2018 01:22 AM, Nicolas Goaziou wrote:
> It looks good. Could you send it on this ML as a patch so I can comment
> it more conveniently?

Since you want to comment I guess you want the patch in the e-mail body 
rather than attached. Here goes nothing.

 From bb02cd6c00b32155c0a25f409f1bfa4160b2ddcd Mon Sep 17 00:00:00 2001
From: Jesse Johnson <holocronweaver@gmail.com>
Date: Sun, 22 Apr 2018 18:12:54 -0700
Subject: [PATCH] Add priority inheritance

* New org-use-priority-inheritance defcustom to toggle inheritance.
* org-get-priority now takes a pos and implements inheritance.
* org-get-priority-function can make use of inheritance by returning t.
* org-agenda-fix-displayed-priority ensures inherited priority is
   visible.
* Updates where priority is used so that inheritance is respected.  As
   a side effect, org-get-priority-function is now more widely
   respected.
---
  lisp/org-agenda.el | 117 
+++++++++++++++++++++++++++++++++--------------------
  lisp/org-habit.el  |  16 ++++----
  lisp/org.el        | 102 ++++++++++++++++++++++++++++++++++------------
  3 files changed, 157 insertions(+), 78 deletions(-)

diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index eaeddb6..e18e73d 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -4581,6 +4581,7 @@ is active."
              (setq marker (org-agenda-new-marker (point))
                    category (org-get-category)
                    level (make-string (org-reduced-level 
(org-outline-level)) ? )
+                              priority (org-get-priority)
                    inherited-tags
                    (or (eq org-agenda-show-inherited-tags 'always)
                    (and (listp org-agenda-show-inherited-tags)
@@ -4593,13 +4594,13 @@ is active."
                     ""
                     (buffer-substring-no-properties
                      beg1 (point-at-eol))
-                   level category tags t))
+                   level category priority tags t))
              (org-add-props txt props
                'org-marker marker 'org-hd-marker marker
                'org-todo-regexp org-todo-regexp
                'level level
                'org-complex-heading-regexp org-complex-heading-regexp
-              'priority 1000
+              'priority priority
                'type "search")
              (push txt ee)
              (goto-char (1- end))))))))))
@@ -5078,7 +5079,7 @@ of what a project is and how to check if it stuck, 
customize the variable
        (setq entries
          (mapcar
           (lambda (x)
-           (setq x (org-agenda-format-item "" x nil "Diary" nil 'time))
+           (setq x (org-agenda-format-item "" x nil "Diary" nil nil 'time))
             ;; Extend the text properties to the beginning of the line
             (org-add-props x (text-properties-at (1- (length x)) x)
           'type "diary" 'date date 'face 'org-agenda-diary))
@@ -5361,6 +5362,7 @@ and the timestamp type relevant for the sorting 
strategy in
            ts-date (car ts-date-pair)
            ts-date-type (cdr ts-date-pair)
            txt (org-trim (buffer-substring (match-beginning 2) 
(match-end 0)))
+              priority (1+ (org-get-priority))
            inherited-tags
            (or (eq org-agenda-show-inherited-tags 'always)
            (and (listp org-agenda-show-inherited-tags)
@@ -5370,8 +5372,7 @@ and the timestamp type relevant for the sorting 
strategy in
                 (memq 'todo org-agenda-use-tag-inheritance))))
            tags (org-get-tags nil (not inherited-tags))
            level (make-string (org-reduced-level (org-outline-level)) ? )
-          txt (org-agenda-format-item "" txt level category tags t)
-          priority (1+ (org-get-priority txt)))
+          txt (org-agenda-format-item "" txt level category priority 
tags t))
      (org-add-props txt props
        'org-marker marker 'org-hd-marker marker
        'priority priority
@@ -5570,6 +5571,9 @@ displayed in agenda view."
                 (assq (point) deadline-position-alist))
            (throw :skip nil))
          (let* ((category (org-get-category pos))
+                   (priority (if habit?
+                                 (org-habit-get-priority 
(org-habit-parse-todo))
+                               (org-get-priority item)))
             (inherited-tags
              (or (eq org-agenda-show-inherited-tags 'always)
              (and (consp org-agenda-show-inherited-tags)
@@ -5588,11 +5592,10 @@ displayed in agenda view."
             (item
              (org-agenda-format-item
               (and inactive? org-agenda-inactive-leader)
-             head level category tags time-stamp org-ts-regexp habit?)))
+             head level category priority tags
+                     time-stamp org-ts-regexp habit?)))
            (org-add-props item props
-        'priority (if habit?
-                  (org-habit-get-priority (org-habit-parse-todo))
-                (org-get-priority item))
+        'priority priority
          'org-marker (org-agenda-new-marker pos)
          'org-hd-marker (org-agenda-new-marker)
          'date date
@@ -5635,6 +5638,7 @@ displayed in agenda view."
        (setq marker (org-agenda-new-marker beg)
          level (make-string (org-reduced-level (org-outline-level)) ? )
          category (org-get-category beg)
+                priority (org-get-priority)
          inherited-tags
          (or (eq org-agenda-show-inherited-tags 'always)
              (and (listp org-agenda-show-inherited-tags)
@@ -5657,7 +5661,7 @@ displayed in agenda view."
          (if (string-match "\\S-" r)
          (setq txt r)
            (setq txt "SEXP entry returned empty string"))
-        (setq txt (org-agenda-format-item extra txt level category tags 
'time))
+        (setq txt (org-agenda-format-item extra txt level category 
priority tags 'time))
          (org-add-props txt props 'org-marker marker
                 'date date 'todo-state todo-state
                 'level level 'type "sexp" 'warntime warntime)
@@ -5785,6 +5789,7 @@ then those holidays will be skipped."
            (throw :skip nil)
          (goto-char (match-beginning 0))
          (setq hdmarker (org-agenda-new-marker)
+                  priority (org-get-priority)
            inherited-tags
            (or (eq org-agenda-show-inherited-tags 'always)
                (and (listp org-agenda-show-inherited-tags)
@@ -5806,8 +5811,7 @@ then those holidays will be skipped."
              (closedp "Closed:    ")
              (statep (concat "State:     (" state ")"))
              (t (concat "Clocked:   (" clocked  ")")))
-               txt level category tags timestr)))
-      (setq priority 100000)
+               txt level category priority tags timestr)))
        (org-add-props txt props
          'org-marker marker 'org-hd-marker hdmarker 'face 'org-agenda-done
          'priority priority 'level level
@@ -6032,6 +6036,13 @@ specification like [h]h:mm."
             (level (make-string (org-reduced-level (org-outline-level))
                         ?\s))
             (head (buffer-substring (point) (line-end-position)))
+                   (priority
+                    ;; Adjust priority to today reminders about deadlines.
+                    ;; Overdue deadlines get the highest priority
+                    ;; increase, then imminent deadlines and eventually
+                    ;; more distant deadlines.
+                    (let ((adjust (if today? (- diff) 0)))
+                      (+ adjust (org-get-priority))))
             (inherited-tags
              (or (eq org-agenda-show-inherited-tags 'always)
              (and (listp org-agenda-show-inherited-tags)
@@ -6059,7 +6070,7 @@ specification like [h]h:mm."
              ((and today? (< deadline today)) (format past (- diff)))
              ((and today? (> deadline today)) (format future diff))
              (t now)))
-             head level category tags time))
+             head level category priority tags time))
             (face (org-agenda-deadline-face
                (- 1 (/ (float diff) (max wdays 1)))))
             (upcoming? (and today? (> deadline today)))
@@ -6070,13 +6081,7 @@ specification like [h]h:mm."
          'warntime warntime
          'level level
          'ts-date deadline
-        'priority
-        ;; Adjust priority to today reminders about deadlines.
-        ;; Overdue deadlines get the highest priority
-        ;; increase, then imminent deadlines and eventually
-        ;; more distant deadlines.
-        (let ((adjust (if today? (- diff) 0)))
-          (+ adjust (org-get-priority item)))
+        'priority priority
          'todo-state todo-state
          'type (if upcoming? "upcoming-deadline" "deadline")
          'date (if upcoming? date deadline)
@@ -6222,16 +6227,19 @@ scheduled items with an hour specification like 
[h]h:mm."
        ;; Skip habits if `org-habit-show-habits' is nil, or if we
        ;; only show them for today.  Also skip done habits.
        (when (and habitp
-             (or donep
-             (not (bound-and-true-p org-habit-show-habits))
-             (and (not todayp)
-                  (bound-and-true-p
-                   org-habit-show-habits-only-for-today))))
+                     (or donep
+                         (not (bound-and-true-p org-habit-show-habits))
+                         (and (not todayp)
+                              (bound-and-true-p
+ org-habit-show-habits-only-for-today))))
          (throw :skip nil))
        (save-excursion
          (re-search-backward "^\\*+[ \t]+" nil t)
          (goto-char (match-end 0))
          (let* ((category (org-get-category))
+                   (habit (and habitp (org-habit-parse-todo)))
+                   (priority (if habit (org-habit-get-priority habit)
+                               (+ 99 diff (org-get-priority))))
             (inherited-tags
              (or (eq org-agenda-show-inherited-tags 'always)
              (and (listp org-agenda-show-inherited-tags)
@@ -6259,12 +6267,11 @@ scheduled items with an hour specification like 
[h]h:mm."
                 (if (and todayp pastschedp)
                 (format past diff)
               first))
-             head level category tags time nil habitp))
+             head level category priority tags time nil habitp))
             (face (cond ((and (not habitp) pastschedp)
                  'org-scheduled-previously)
                     (todayp 'org-scheduled-today)
-                   (t 'org-scheduled)))
-           (habitp (and habitp (org-habit-parse-todo))))
+                   (t 'org-scheduled))))
            (org-add-props item props
          'undone-face face
          'face (if donep 'org-agenda-done face)
@@ -6275,9 +6282,8 @@ scheduled items with an hour specification like 
[h]h:mm."
          'ts-date schedule
          'warntime warntime
          'level level
-        'priority (if habitp (org-habit-get-priority habitp)
-                (+ 99 diff (org-get-priority item)))
-        'org-habit-p habitp
+        'priority priority
+        'org-habit-p habit
          'todo-state todo-state)
            (push item scheduled-items))))))
      (nreverse scheduled-items)))
@@ -6295,7 +6301,7 @@ scheduled items with an hour specification like 
[h]h:mm."
       (regexp org-tr-regexp)
       (d0 (calendar-absolute-from-gregorian date))
       marker hdmarker ee txt d1 d2 s1 s2 category
-     level todo-state tags pos head donep inherited-tags)
+     level priority todo-state tags pos head donep inherited-tags)
      (goto-char (point-min))
      (while (re-search-forward regexp nil t)
        (catch :skip
@@ -6346,7 +6352,7 @@ scheduled items with an hour specification like 
[h]h:mm."
                (and (eq org-agenda-show-inherited-tags t)
                     (or (eq org-agenda-use-tag-inheritance t)
                     (memq 'agenda org-agenda-use-tag-inheritance))))
-
+              priority (org-get-priority)
                tags (org-get-tags nil (not inherited-tags)))
          (setq level (make-string (org-reduced-level 
(org-outline-level)) ? ))
          (looking-at "\\*+[ \t]+\\(.*\\)")
@@ -6363,7 +6369,7 @@ scheduled items with an hour specification like 
[h]h:mm."
                    (nth (if (= d1 d2) 0 1)
                     org-agenda-timerange-leaders)
                    (1+ (- d0 d1)) (1+ (- d2 d1)))
-                 head level category tags
+                 head level category priority tags
                   (cond ((and (= d1 d0) (= d2 d0))
                      (concat "<" start-time ">--<" end-time ">"))
                                     ((= d1 d0)
@@ -6376,11 +6382,11 @@ scheduled items with an hour specification like 
[h]h:mm."
          'type "block" 'date date
          'level level
          'todo-state todo-state
-        'priority (org-get-priority txt))
+        'priority priority)
            (push txt ee))))
-    (goto-char pos)))
-    ;; Sort the entries by expiration date.
-    (nreverse ee)))
+      (goto-char pos)))
+  ;; Sort the entries by expiration date.
+  (nreverse ee)))

  ;;; Agenda presentation and sorting

@@ -6409,8 +6415,9 @@ The flag is set if the currently compiled format 
contains a `%b'.")
        (cl-return (cadr entry))
      (cl-return (apply #'create-image (cdr entry)))))))

-(defun org-agenda-format-item (extra txt &optional level category tags 
dotime
-                     remove-re habitp)
+(defun org-agenda-format-item (extra txt
+                                     &optional level category priority tags
+                                     dotime remove-re habitp)
    "Format TXT to be inserted into the agenda buffer.
  In particular, add the prefix and corresponding text properties.

@@ -6419,10 +6426,11 @@ LEVEL may be a string to replace the `%l' specifier.
  CATEGORY (a string, a symbol or nil) may be used to overrule the default
  category taken from local variable or file name.  It will replace the `%c'
  specifier in the format.
+PRIORITY can be the integer priority of the headline.
+TAGS can be the tags of the headline.
  DOTIME, when non-nil, indicates that a time-of-day should be extracted 
from
  TXT for sorting of this entry, and for the `%t' specifier in the format.
  When DOTIME is a string, this string is searched for a time before TXT is.
-TAGS can be the tags of the headline.
  Any match of REMOVE-RE will be removed from TXT."
    ;; We keep the org-prefix-* variable values along with a compiled
    ;; formatter, so that multiple agendas existing at the same time do
@@ -6440,6 +6448,9 @@ Any match of REMOVE-RE will be removed from TXT."
        ;; Diary entries sometimes have extra whitespace at the beginning
        (setq txt (org-trim txt))

+      ;; Fix the priority part in txt
+      (setq txt (org-agenda-fix-displayed-priority txt priority))
+
        ;; Fix the tags part in txt
        (setq txt (org-agenda-fix-displayed-tags
           txt tags
@@ -6611,6 +6622,20 @@ The modified list may contain inherited tags, and 
tags matched by
                (if have-i "::" ":"))))))
    txt)

+(defun org-agenda-fix-displayed-priority (txt priority)
+  "Modifies TXT to show correct PRIORITY.
+Respects `org-use-priority-inheritance' by adding PRIORITY if not
+already present. No change is made if `org-get-priority-function'
+is non-nil since TXT may be using non-standard priority cookies."
+  (when (and priority
+             org-use-priority-inheritance
+             (not (functionp org-get-priority-function))
+             (not (string-match org-priority-regexp txt)))
+    (let ((priority-str
+           (char-to-string (org-priority-integer-to-char priority))))
+      (setq txt (concat "[#" priority-str "] " txt))))
+  txt)
+
  (defun org-downcase-keep-props (s)
    (let ((props (text-properties-at 0 s)))
      (setq s (downcase s))
@@ -6646,14 +6671,14 @@ TODAYP is t when the current agenda view is on 
today."
      (unless (and remove (member time have))
        (setq time (replace-regexp-in-string " " "0" (format "%04s" time)))
        (push (org-agenda-format-item
-         nil string nil "" nil
+         nil string nil "" nil nil nil
           (concat (substring time 0 -2) ":" (substring time -2)))
          new)
        (put-text-property
         2 (length (car new)) 'face 'org-time-grid (car new))))
        (when (and todayp org-agenda-show-current-time-in-grid)
      (push (org-agenda-format-item
-           nil org-agenda-current-time-string nil "" nil
+           nil org-agenda-current-time-string nil "" nil nil nil
             (format-time-string "%H:%M "))
            new)
      (put-text-property
@@ -8932,6 +8957,10 @@ If FORCE-TAGS is non nil, the car of it returns 
the new tags."
    (let* ((inhibit-read-only t)
       (line (org-current-line))
       (org-agenda-buffer (current-buffer))
+         (priority (with-current-buffer (marker-buffer hdmarker)
+                     (org-with-wide-buffer
+                      (goto-char hdmarker)
+                      (org-get-priority))))
       (thetags (with-current-buffer (marker-buffer hdmarker)
              (org-get-tags hdmarker)))
       props m pl undone-face done-face finish new dotime level cat tags)
@@ -8955,7 +8984,7 @@ If FORCE-TAGS is non nil, the car of it returns 
the new tags."
                (extra (org-get-at-bol 'extra)))
            (with-current-buffer (marker-buffer hdmarker)
              (org-with-wide-buffer
-             (org-agenda-format-item extra newhead level cat tags 
dotime))))
+             (org-agenda-format-item extra newhead level cat priority 
tags dotime))))
          pl (text-property-any (point-at-bol) (point-at-eol) 
'org-heading t)
          undone-face (org-get-at-bol 'undone-face)
          done-face (org-get-at-bol 'done-face))
diff --git a/lisp/org-habit.el b/lisp/org-habit.el
index 375714e..2d5d0d8 100644
--- a/lisp/org-habit.el
+++ b/lisp/org-habit.el
@@ -248,23 +248,23 @@ This list represents a \"habit\" for the rest of 
this module."
  (defsubst org-habit-get-priority (habit &optional moment)
    "Determine the relative priority of a habit.
  This must take into account not just urgency, but consistency as well."
-  (let ((pri 1000)
-    (now (if moment (time-to-days moment) (org-today)))
-    (scheduled (org-habit-scheduled habit))
-    (deadline (org-habit-deadline habit)))
+  (let ((pri (org-get-priority))
+        (now (if moment (time-to-days moment) (org-today)))
+        (scheduled (org-habit-scheduled habit))
+        (deadline (org-habit-deadline habit)))
      ;; add 10 for every day past the scheduled date, and subtract for 
every
      ;; day before it
      (setq pri (+ pri (* (- now scheduled) 10)))
      ;; add 50 if the deadline is today
      (if (and (/= scheduled deadline)
-         (= now deadline))
-    (setq pri (+ pri 50)))
+             (= now deadline))
+        (setq pri (+ pri 50)))
      ;; add 100 for every day beyond the deadline date, and subtract 10 for
      ;; every day before it
      (let ((slip (- now (1- deadline))))
        (if (> slip 0)
-      (setq pri (+ pri (* slip 100)))
-    (setq pri (+ pri (* slip 10)))))
+          (setq pri (+ pri (* slip 100)))
+        (setq pri (+ pri (* slip 10)))))
      pri))

  (defun org-habit-get-faces (habit &optional now-days scheduled-days donep)
diff --git a/lisp/org.el b/lisp/org.el
index 66eb2f3..768b84a 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -3175,18 +3175,46 @@ See also `org-default-priority'."
    :type 'boolean)

  (defcustom org-get-priority-function nil
-  "Function to extract the priority from a string.
-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
-an integer, increasing by 1000 for each priority level.
-The user can set a different function here, which should take a string
-as an argument and return the numeric priority."
+  "Function to extract the priority from current line.
+The line is always a headline.
+
+If this is nil Org computes the priority of the headline from a
+priority cookie like [#A]. It returns an integer, increasing by
+1000 for each priority level (see
+`org-priority-char-to-integer').
+
+The user can set a different function here, which should process
+the current line and return one of:
+
+- an integer priority
+- nil if current line is not a header or otherwise has no
+associated priority
+- t if the `org-default-priority' should be used or the priority can be
+inherited from its parent
+
+Priority can only be inherited if `org-use-priority-inheritance' is
+non-nil."
    :group 'org-priorities
    :version "24.1"
    :type '(choice
        (const nil)
        (function)))

+(defcustom org-use-priority-inheritance nil
+  "Whether headline priority is inherited from its parents.
+
+If non-nil then the first explicit priority found when searching
+up the headline tree applies.  Thus a child headline can override
+its parent's priority.
+
+When nil, explicit priorities only apply to the headline they are
+given on.
+
+Regardless of setting, if no explicit priority is found then the
+default priority is used."
+  :group 'org-priorities
+  :type 'boolean)
+
  (defgroup org-time nil
    "Options concerning time stamps and deadlines in Org mode."
    :tag "Org Time"
@@ -13633,22 +13661,43 @@ and by additional input from the age of a 
schedules or deadline entry."
    (interactive)
    (let ((pri (if (eq major-mode 'org-agenda-mode)
           (org-get-at-bol 'priority)
-           (save-excursion
-         (save-match-data
-           (beginning-of-line)
-           (and (looking-at org-heading-regexp)
-            (org-get-priority (match-string 0))))))))
+           (org-get-priority))))
      (message "Priority is %d" (if pri pri -1000))))

-(defun org-get-priority (s)
-  "Find priority cookie and return priority."
-  (save-match-data
-    (if (functionp org-get-priority-function)
-    (funcall org-get-priority-function)
-      (if (not (string-match org-priority-regexp s))
-      (* 1000 (- org-lowest-priority org-default-priority))
-    (* 1000 (- org-lowest-priority
-           (string-to-char (match-string 2 s))))))))
+(defun org-priority-char-to-integer (character)
+  "Convert priority CHARACTER to an integer priority."
+  (* 1000 (- org-lowest-priority character)))
+
+(defun org-priority-integer-to-char (integer)
+  "Convert priority INTEGER to a character priority."
+  (- org-lowest-priority (/ integer 1000)))
+
+(defun org-get-priority (&optional pos local)
+  "Get integer priority at POS.
+POS defaults to point.  If LOCAL is non-nil priority inheritance
+is ignored regardless of the value of
+`org-use-priority-inheritance'.  Returns nil if no priority can be
+determined at POS."
+  (save-excursion
+    (save-restriction
+      (widen)
+      (goto-char (or pos (point)))
+      (beginning-of-line)
+      (if (not (looking-at org-heading-regexp))
+      (return nil)
+    (save-match-data
+      (cl-loop
+       (if (functionp org-get-priority-function)
+           (let ((priority (funcall org-get-priority-function)))
+         (unless (eq priority t)
+           (return priority)))
+         (when (looking-at org-priority-regexp)
+           (return (org-priority-char-to-integer
+            (string-to-char (match-string-no-properties 2))))))
+       (unless (and (not local)
+            org-use-priority-inheritance
+            (org-up-heading-safe))
+         (return (org-priority-char-to-integer 
org-default-priority)))))))))

  ;;;; Tags

@@ -13713,6 +13762,7 @@ headlines matching this string."
                     (or (buffer-file-name (buffer-base-buffer))
                     (buffer-name (buffer-base-buffer)))))))
       (org-map-continue-from nil)
+         priority
           lspos tags tags-list
       (tags-alist (list (cons 0 org-file-tags)))
       (llast 0) rtn rtn1 level category i txt
@@ -13800,7 +13850,8 @@ headlines matching this string."
              (match-beginning 1) (match-end 1)))
            (org-show-context 'tags-tree))
           ((eq action 'agenda)
-          (setq txt (org-agenda-format-item
+          (setq priority (org-get-priority)
+            txt (org-agenda-format-item
               ""
               (concat
                (if (eq org-tags-match-list-sublevels 'indented)
@@ -13808,8 +13859,8 @@ headlines matching this string."
                (org-get-heading))
               (make-string level ?\s)
               category
-             tags-list)
-            priority (org-get-priority txt))
+                         priority
+             tags-list))
            (goto-char lspos)
            (setq marker (org-agenda-new-marker))
            (org-add-props txt props
@@ -15066,9 +15117,8 @@ strings."
            (when specific (throw 'exit props)))
          (when (or (not specific) (string= specific "PRIORITY"))
            (push (cons "PRIORITY"
-              (if (looking-at org-priority-regexp)
-                  (match-string-no-properties 2)
-                (char-to-string org-default-priority)))
+                          (char-to-string
+                           (org-priority-integer-to-char 
(org-get-priority))))
              props)
            (when specific (throw 'exit props)))
          (when (or (not specific) (string= specific "FILE"))
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: inherit priority
  2018-07-10  5:03                   ` Jesse Johnson
@ 2018-07-18 12:54                     ` Nicolas Goaziou
  0 siblings, 0 replies; 15+ messages in thread
From: Nicolas Goaziou @ 2018-07-18 12:54 UTC (permalink / raw)
  To: Jesse Johnson; +Cc: Bastien, emacs-orgmode

Hello,

Jesse Johnson <holocronweaver@gmail.com> writes:

> Since you want to comment I guess you want the patch in the e-mail
> body rather than attached. Here goes nothing.

Thank you!

It looks good. Some minor comments follow.

> From bb02cd6c00b32155c0a25f409f1bfa4160b2ddcd Mon Sep 17 00:00:00 2001
> From: Jesse Johnson <holocronweaver@gmail.com>
> Date: Sun, 22 Apr 2018 18:12:54 -0700
> Subject: [PATCH] Add priority inheritance

You need to describe here what functions or variables changed here,
e.g.,

  * lisp/org-agenda (org-search-view): ...

>  (defcustom org-get-priority-function nil
> -  "Function to extract the priority from a string.
> -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
> -an integer, increasing by 1000 for each priority level.
> -The user can set a different function here, which should take a string
> -as an argument and return the numeric priority."
> +  "Function to extract the priority from current line.
> +The line is always a headline.
> +
> +If this is nil Org computes the priority of the headline from a
> +priority cookie like [#A]. It returns an integer, increasing by

You need to add two spaces after a full stop.

> +1000 for each priority level (see
> +`org-priority-char-to-integer').

> +(defcustom org-use-priority-inheritance nil
> +  "Whether headline priority is inherited from its parents.

"Non-nil means headline priority is..."

> +If non-nil then the first explicit priority found when searching
> +up the headline tree applies.  Thus a child headline can override
> +its parent's priority.
> +
> +When nil, explicit priorities only apply to the headline they are
> +given on.
> +
> +Regardless of setting, if no explicit priority is found then the
> +default priority is used."
> +  :group 'org-priorities
> +  :type 'boolean)

You need to add the following keywords: 

  :package-version '(Org . "9.3")

and possibly 

  :safe t

> +(defun org-priority-char-to-integer (character)
> +  "Convert priority CHARACTER to an integer priority."
> +  (* 1000 (- org-lowest-priority character)))
> +
> +(defun org-priority-integer-to-char (integer)
> +  "Convert priority INTEGER to a character priority."
> +  (- org-lowest-priority (/ integer 1000)))

I think those can be internal functions, so they should be renamed
`org--priority-char-to-integer' and `org--priority-integer-to-char'.

> +(defun org-get-priority (&optional pos local)
> +  "Get integer priority at POS.
> +POS defaults to point.  If LOCAL is non-nil priority inheritance
> +is ignored regardless of the value of
> +`org-use-priority-inheritance'.  Returns nil if no priority can be

Return nil if...

> +determined at POS."
> +  (save-excursion
> +    (save-restriction
> +      (widen)
> +      (goto-char (or pos (point)))

`save-excursion' + `save-restriction' + `widen' + `goto-char' = `org-with-point-at'

So the above would be:

  (org-with-point-at pos
    ...)

> +      (beginning-of-line)
> +      (if (not (looking-at org-heading-regexp))
> +      (return nil)

Indentation looks wrong, but it should be:

  (unless (looking-at org-heading-regexp)
    ...)

> +    (save-match-data
> +      (cl-loop
> +       (if (functionp org-get-priority-function)
> +           (let ((priority (funcall org-get-priority-function)))
> +         (unless (eq priority t)
> +           (return priority)))
> +         (when (looking-at org-priority-regexp)
> +           (return (org-priority-char-to-integer
> +            (string-to-char (match-string-no-properties 2))))))
> +       (unless (and (not local)
> +            org-use-priority-inheritance
> +            (org-up-heading-safe))
> +         (return (org-priority-char-to-integer
> org-default-priority)))))))))

You can write a simpler function. Please have a look at `org-get-tags'
and use `org-complex-heading-regexp' to get priority cookie.

Also could you throw in a bunch of tests in "contrib/lisp/test-org.el"
and update the manual accordingly?

Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2018-07-18 12:54 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-31 18:14 inherit priority Jesse Johnson
2018-01-03 21:41 ` Nicolas Goaziou
2018-01-04  4:04   ` Jesse Johnson
2018-01-04  8:15     ` Nicolas Goaziou
2018-01-05  4:00       ` Jesse Johnson
2018-01-05  7:24         ` Nicolas Goaziou
2018-01-07 22:47           ` Jesse Johnson
2018-01-08 13:16             ` Nicolas Goaziou
2018-04-26 23:34         ` Bastien
2018-04-27  1:34           ` Jesse Johnson
2018-04-27  1:59             ` Bastien
2018-07-08  1:55               ` Jesse Johnson
2018-07-09  8:22                 ` Nicolas Goaziou
2018-07-10  5:03                   ` Jesse Johnson
2018-07-18 12:54                     ` Nicolas Goaziou

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).