Replace org-mode-p with usual (eq major-mode 'org-mode) check
[org-mode.git] / lisp / org-agenda.el
index d665b54..a5f58b7 100644 (file)
@@ -1,12 +1,10 @@
 ;;; org-agenda.el --- Dynamic task and appointment lists for Org
 
-;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 2004-2011 Free Software Foundation, Inc.
 
 ;; Author: Carsten Dominik <carsten at orgmode dot org>
 ;; Keywords: outlines, hypermedia, calendar, wp
 ;; Homepage: http://orgmode.org
-;; Version: 7.5
 ;;
 ;; This file is part of GNU Emacs.
 ;;
 ;;; Commentary:
 
 ;; This file contains the code for creating and using the Agenda for Org-mode.
+;;
+;; The functions `org-batch-agenda', `org-batch-agenda-csv', and
+;; `org-batch-store-agenda-views' are implemented as macros to provide
+;; a conveniant way for extracting agenda information from the command
+;; line. The Lisp does not evaluate parameters of a macro call; thus
+;; it is not necessary to quote the parameters passed to one of those
+;; functions. E.g. you can write:
+;;
+;;   emacs -batch -l ~/.emacs -eval '(org-batch-agenda "a" org-agenda-span 7)'
+;;
+;; To export an agenda spanning 7 days. If `org-batch-agenda' would
+;; have been implemented as a regular function you'd have to quote the
+;; symbol org-agenda-span. Moreover: To use a symbol as parameter
+;; value you would have to double quote the symbol.
+;;
+;; This is a hack, but it works even when running Org byte-compiled.
+;;
 
 ;;; Code:
 
@@ -61,6 +76,9 @@
 (declare-function org-is-habit-p "org-habit" (&optional pom))
 (declare-function org-habit-parse-todo "org-habit" (&optional pom))
 (declare-function org-habit-get-priority "org-habit" (habit &optional moment))
+(declare-function org-pop-to-buffer-same-window "org-compat"
+                 (&optional buffer-or-name norecord label))
+
 (defvar calendar-mode-map)
 (defvar org-clock-current-task) ; defined in org-clock.el
 (defvar org-mobile-force-id-on-agenda-items) ; defined in org-mobile.el
@@ -89,16 +107,20 @@ only needed when the text to be killed contains more than N non-white lines."
 
 (defcustom org-agenda-compact-blocks nil
   "Non-nil means make the block agenda more compact.
-This is done by leaving out unnecessary lines."
+This is done globally by leaving out lines like the agenda span
+name and week number or the separator lines."
   :group 'org-agenda
   :type 'boolean)
 
 (defcustom org-agenda-block-separator ?=
   "The separator between blocks in the agenda.
 If this is a string, it will be used as the separator, with a newline added.
-If it is a character, it will be repeated to fill the window width."
+If it is a character, it will be repeated to fill the window width.
+If nil the separator is disabled.  In `org-agenda-custom-commands' this
+addresses the separator between the current and the previous block."
   :group 'org-agenda
   :type '(choice
+         (const :tag "Disabled" nil)
          (character)
          (string)))
 
@@ -326,7 +348,8 @@ This will be spliced into the custom type of
 `org-agenda-custom-commands'.")
 
 
-(defcustom org-agenda-custom-commands nil
+(defcustom org-agenda-custom-commands '(("n" "Agenda and all TODO's"
+                                        ((agenda "") (alltodo))))
   "Custom commands for the agenda.
 These commands will be offered on the splash screen displayed by the
 agenda dispatcher \\[org-agenda].  Each entry is a list like this:
@@ -764,7 +787,7 @@ because you will take care of it on the day when scheduled."
          (const :tag "Remove prewarning if entry is scheduled" t)
          (integer :tag "Restart prewarning N days before deadline")))
 
-(defcustom org-agenda-skip-additional-timestamps-same-entry t
+(defcustom org-agenda-skip-additional-timestamps-same-entry nil
   "When nil, multiple same-day timestamps in entry make multiple agenda lines.
 When non-nil, after the search for timestamps has matched once in an
 entry, the rest of the entry will not be searched."
@@ -849,6 +872,12 @@ Needs to be set before org.el is loaded."
   :group 'org-agenda-startup
   :type 'boolean)
 
+(defcustom org-agenda-follow-indirect nil
+  "Non-nil means `org-agenda-follow-mode' displays only the
+current item's tree, in an indirect buffer."
+  :group 'org-agenda
+  :type 'boolean)
+
 (defcustom org-agenda-show-outline-path t
   "Non-nil means show outline path in echo area after line motion."
   :group 'org-agenda-startup
@@ -1044,6 +1073,15 @@ and timeline buffers."
              (const :tag "Saturday" 6)
              (const :tag "Sunday" 0)))
 
+(defcustom org-agenda-move-date-from-past-immediately-to-today t
+  "Non-nil means jumpt to today when moving a past date forward in time.
+When using S-right in the agenda to move a a date forward, and the date
+stamp currently points to the past, the first key press will move it
+to today.  WHen nil, just move one day forward even if the date stays
+in the past."
+  :group 'org-agenda-daily/weekly
+  :type 'boolean)
+
 (defcustom org-agenda-include-diary nil
   "If non-nil, include in the agenda entries from the Emacs Calendar's diary.
 Custom commands can set this variable in the options section."
@@ -1056,14 +1094,6 @@ Custom commands can set this variable in the options section."
   :group 'org-agenda-daily/weekly
   :type 'boolean)
 
-(defcustom org-agenda-include-all-todo nil
-  "Set  means weekly/daily agenda will always contain all TODO entries.
-The TODO entries will be listed at the top of the agenda, before
-the entries for specific days.
-This option is deprecated, it is better to define a block agenda instead."
-  :group 'org-agenda-daily/weekly
-  :type 'boolean)
-
 (defcustom org-agenda-repeating-timestamp-show-all t
   "Non-nil means show all occurrences of a repeating stamp in the agenda.
 When set to a list of strings, only show occurrences of repeating
@@ -1384,34 +1414,32 @@ When nil, such items are sorted as 0 minutes effort."
     (tags  . " %i %-12:c")
     (search . " %i %-12:c"))
   "Format specifications for the prefix of items in the agenda views.
-An alist with four entries, for the different agenda types.  The keys to the
-sublists are `agenda', `timeline', `todo', `search' and `tags'.  The values
-are format strings.
+An alist with five entries, each for the different agenda types.  The
+keys of the sublists are `agenda', `timeline', `todo', `search' and `tags'.
+The values are format strings.
+
 This format works similar to a printf format, with the following meaning:
 
-  %c   the category of the item, \"Diary\" for entries from the diary, or
-       as given by the CATEGORY keyword or derived from the file name.
-  %i   the icon category of the item, as give in
-       `org-agenda-category-icon-alist'.
-  %T   the *last* tag of the item.  Last because inherited tags come
-       first in the list.
-  %t   the time-of-day specification if one applies to the entry, in the
-       format HH:MM
+  %c   the category of the item, \"Diary\" for entries from the diary,
+       or as given by the CATEGORY keyword or derived from the file name
+  %e   the effort required by the item
+  %i   the icon category of the item, see `org-agenda-category-icon-alist'
+  %T   the last tag of the item (ignore inherited tags, which come first)
+  %t   the HH:MM time-of-day specification if one applies to the entry
   %s   Scheduling/Deadline information, a short string
   %(expression) Eval EXPRESSION and replace the control string
                 by the result
 
 All specifiers work basically like the standard `%s' of printf, but may
-contain two additional characters:  A question mark just after the `%' and
-a whitespace/punctuation character just before the final letter.
+contain two additional characters:  a question mark just after the `%'
+and a whitespace/punctuation character just before the final letter.
 
 If the first character after `%' is a question mark, the entire field
-will only be included if the corresponding value applies to the
-current entry.  This is useful for fields which should have fixed
-width when present, but zero width when absent.  For example,
-\"%?-12t\" will result in a 12 character time field if a time of the
-day is specified, but will completely disappear in entries which do
-not contain a time.
+will only be included if the corresponding value applies to the current
+entry.  This is useful for fields which should have fixed width when
+present, but zero width when absent.  For example, \"%?-12t\" will
+result in a 12 character time field if a time of the day is specified,
+but will completely disappear in entries which do not contain a time.
 
 If there is punctuation or whitespace character just before the final
 format letter, this character will be appended to the field value if
@@ -1419,19 +1447,16 @@ the value is not empty.  For example, the format \"%-12:c\" leads to
 \"Diary: \" if the category is \"Diary\".  If the category were be
 empty, no additional colon would be inserted.
 
-The default value of this option is \"  %-12:c%?-12t% s\", meaning:
+The default value for the agenda sublist is \"  %-12:c%?-12t% s\",
+which means:
+
 - Indent the line with two space characters
-- Give the category in a 12 chars wide field, padded with whitespace on
+- Give the category a 12 chars wide field, padded with whitespace on
   the right (because of `-').  Append a colon if there is a category
   (because of `:').
 - If there is a time-of-day, put it into a 12 chars wide field.  If no
   time, don't put in an empty field, just skip it (because of '?').
-- Finally, put the scheduling information and append a whitespace.
-
-As another example, if you don't want the time-of-day of entries in
-the prefix, you could use:
-
-  (setq org-agenda-prefix-format \"  %-11:c% s\")
+- Finally, put the scheduling information.
 
 See also the variables `org-agenda-remove-times-when-in-prefix' and
 `org-agenda-remove-tags'.
@@ -1691,6 +1716,19 @@ the lower-case version of all tags."
   :group 'org-agenda
   :type 'function)
 
+(defcustom org-agenda-bulk-custom-functions nil
+  "Alist of characters and custom functions for bulk actions.
+For example, this value makes those two functions available:
+
+  '((?R set-category)
+    (?C bulk-cut))
+
+With selected entries in an agenda buffer, `B R' will call
+the custom function `set-category' on the selected entries.
+Note that functions in this alist don't need to be quoted."
+  :type 'alist
+  :group 'org-agenda)
+
 (eval-when-compile
   (require 'cl))
 (require 'org)
@@ -1700,12 +1738,14 @@ the lower-case version of all tags."
 If STRING is non-nil, the text property will be fetched from position 0
 in that string.  If STRING is nil, it will be fetched from the beginning
 of the current line."
-  `(let ((marker (get-text-property (if string 0 (point-at-bol))
-                                   'org-hd-marker string)))
-     (with-current-buffer (marker-buffer marker)
-       (save-excursion
-        (goto-char marker)
-        ,@body))))
+  (org-with-gensyms (marker)
+    `(let ((,marker (get-text-property (if string 0 (point-at-bol))
+                                      'org-hd-marker string)))
+       (with-current-buffer (marker-buffer ,marker)
+        (save-excursion
+          (goto-char ,marker)
+          ,@body)))))
+(def-edebug-spec org-agenda-with-point-at-orig-entry (form body))
 
 (defun org-add-agenda-custom-command (entry)
   "Replace or add a command in `org-agenda-custom-commands'.
@@ -2246,7 +2286,7 @@ Pressing `<' twice means to restrict to the current subtree or region
               ((eq type 'todo-tree)
                (org-check-for-org-mode)
                (org-let lprops
-                 '(org-occur (concat "^" outline-regexp "[ \t]*"
+                 '(org-occur (concat "^" org-outline-regexp "[ \t]*"
                                      (regexp-quote match) "\\>"))))
               ((eq type 'occur-tree)
                (org-check-for-org-mode)
@@ -2284,7 +2324,7 @@ Pressing `<' twice means to restrict to the current subtree or region
                               nil 'face 'org-warning)))))))
         t t))
        ((equal keys "L")
-       (unless (org-mode-p)
+       (unless (eq major-mode 'org-mode)
          (error "This is not an Org-mode file"))
        (unless restriction
          (put 'org-agenda-files 'org-restrict (list bfn))
@@ -2319,7 +2359,7 @@ Agenda views are separated by `org-agenda-block-separator'."
   "The user interface for selecting an agenda command."
   (catch 'exit
     (let* ((bfn (buffer-file-name (buffer-base-buffer)))
-          (restrict-ok (and bfn (org-mode-p)))
+          (restrict-ok (and bfn (eq major-mode 'org-mode)))
           (region-p (org-region-active-p))
           (custom org-agenda-custom-commands)
           (selstring "")
@@ -2561,15 +2601,13 @@ If CMD-KEY is a string of length 1, it is used as a key in
 longer string it is used as a tags/todo match string.
 Parameters are alternating variable names and values that will be bound
 before running the agenda command."
-  (let (pars)
-    (while parameters
-      (push (list (pop parameters) (if parameters (pop parameters))) pars))
+  (org-eval-in-environment (org-make-parameter-alist parameters)
     (if (> (length cmd-key) 2)
-       (eval (list 'let (nreverse pars)
-                   (list 'org-tags-view nil cmd-key)))
-      (eval (list 'let (nreverse pars) (list 'org-agenda nil cmd-key))))
-    (set-buffer org-agenda-buffer-name)
-    (princ (org-encode-for-stdout (buffer-string)))))
+       (org-tags-view nil cmd-key)
+      (org-agenda nil cmd-key)))
+  (set-buffer org-agenda-buffer-name)
+  (princ (org-encode-for-stdout (buffer-string))))
+(def-edebug-spec org-batch-agenda (form &rest sexp))
 
 ;(defun org-encode-for-stdout (string)
 ;  (if (fboundp 'encode-coding-string)
@@ -2616,30 +2654,27 @@ extra        Sting with extra planning info
 priority-l   The priority letter if any was given
 priority-n   The computed numerical priority
 agenda-day   The day in the agenda where this is listed"
-
-  (let (pars)
-    (while parameters
-      (push (list (pop parameters) (if parameters (pop parameters))) pars))
-    (push (list 'org-agenda-remove-tags t) pars)
+  (org-eval-in-environment (append '((org-agenda-remove-tags t))
+                                  (org-make-parameter-alist parameters))
     (if (> (length cmd-key) 2)
-       (eval (list 'let (nreverse pars)
-                   (list 'org-tags-view nil cmd-key)))
-      (eval (list 'let (nreverse pars) (list 'org-agenda nil cmd-key))))
-    (set-buffer org-agenda-buffer-name)
-    (let* ((lines (org-split-string (buffer-string) "\n"))
-          line)
-      (while (setq line (pop lines))
-       (catch 'next
-         (if (not (get-text-property 0 'org-category line)) (throw 'next nil))
-         (setq org-agenda-info
-               (org-fix-agenda-info (text-properties-at 0 line)))
-         (princ
-          (org-encode-for-stdout
-           (mapconcat 'org-agenda-export-csv-mapper
-                      '(org-category txt type todo tags date time extra
-                                     priority-letter priority agenda-day)
-                     ",")))
-         (princ "\n"))))))
+       (org-tags-view nil cmd-key)
+      (org-agenda nil cmd-key)))
+  (set-buffer org-agenda-buffer-name)
+  (let* ((lines (org-split-string (buffer-string) "\n"))
+        line)
+    (while (setq line (pop lines))
+      (catch 'next
+       (if (not (get-text-property 0 'org-category line)) (throw 'next nil))
+       (setq org-agenda-info
+             (org-fix-agenda-info (text-properties-at 0 line)))
+       (princ
+        (org-encode-for-stdout
+         (mapconcat 'org-agenda-export-csv-mapper
+                    '(org-category txt type todo tags date time extra
+                                   priority-letter priority agenda-day)
+                    ",")))
+       (princ "\n")))))
+(def-edebug-spec org-batch-agenda-csv (form &rest sexp))
 
 (defun org-fix-agenda-info (props)
   "Make sure all properties on an agenda item have a canonical form.
@@ -2689,17 +2724,14 @@ This ensures the export commands can easily use it."
   (interactive)
   (eval (list 'org-batch-store-agenda-views)))
 
-;; FIXME, why is this a macro?????
 ;;;###autoload
 (defmacro org-batch-store-agenda-views (&rest parameters)
   "Run all custom agenda commands that have a file argument."
   (let ((cmds (org-agenda-normalize-custom-commands org-agenda-custom-commands))
        (pop-up-frames nil)
        (dir default-directory)
-       pars cmd thiscmdkey files opts cmd-or-set)
-    (while parameters
-      (push (list (pop parameters) (if parameters (pop parameters))) pars))
-    (setq pars (reverse pars))
+       (pars (org-make-parameter-alist parameters))
+       cmd thiscmdkey files opts cmd-or-set)
     (save-window-excursion
       (while cmds
        (setq cmd (pop cmds)
@@ -2709,15 +2741,17 @@ This ensures the export commands can easily use it."
              files (nth (if (listp cmd-or-set) 4 5) cmd))
        (if (stringp files) (setq files (list files)))
        (when files
-         (eval (list 'let (append org-agenda-exporter-settings opts pars)
-                     (list 'org-agenda nil thiscmdkey)))
+         (org-eval-in-environment (append org-agenda-exporter-settings
+                                          opts pars)
+           (org-agenda nil thiscmdkey))
          (set-buffer org-agenda-buffer-name)
          (while files
-           (eval (list 'let (append org-agenda-exporter-settings opts pars)
-                       (list 'org-write-agenda
-                             (expand-file-name (pop files) dir) nil t))))
+           (org-eval-in-environment (append org-agenda-exporter-settings
+                                            opts pars)
+             (org-write-agenda (expand-file-name (pop files) dir) nil t)))
          (and (get-buffer org-agenda-buffer-name)
               (kill-buffer org-agenda-buffer-name)))))))
+(def-edebug-spec org-batch-store-agenda-views (&rest sexp))
 
 (defun org-agenda-mark-header-line (pos)
   "Mark the line at POS as an agenda structure header."
@@ -2871,7 +2905,7 @@ removed from the entry content.  Currently only `planning' is allowed here."
   (let (txt drawer-re kwd-time-re ind)
     (save-excursion
       (with-current-buffer (marker-buffer marker)
-       (if (not (org-mode-p))
+       (if (not (eq major-mode 'org-mode))
            (setq txt "")
          (save-excursion
            (save-restriction
@@ -2987,7 +3021,7 @@ removed from the entry content.  Currently only `planning' is allowed here."
 
 (defun org-check-for-org-mode ()
   "Make sure current buffer is in org-mode.  Error if not."
-  (or (org-mode-p)
+  (or (eq major-mode 'org-mode)
       (error "Cannot execute org-mode agenda command on buffer in %s"
             major-mode)))
 
@@ -3030,7 +3064,8 @@ the global options and expect it to be applied to the entire view.")
       (progn
        (setq buffer-read-only nil)
        (goto-char (point-max))
-       (unless (or (bobp) org-agenda-compact-blocks)
+       (unless (or (bobp) org-agenda-compact-blocks
+                   (not org-agenda-block-separator))
          (insert "\n"
                  (if (stringp org-agenda-block-separator)
                      org-agenda-block-separator
@@ -3053,7 +3088,7 @@ the global options and expect it to be applied to the entire view.")
        (awin (select-window awin))
        ((not (setq org-pre-agenda-window-conf (current-window-configuration))))
        ((equal org-agenda-window-setup 'current-window)
-       (switch-to-buffer abuf))
+       (org-pop-to-buffer-same-window abuf))
        ((equal org-agenda-window-setup 'other-window)
        (org-switch-to-buffer-other-window abuf))
        ((equal org-agenda-window-setup 'other-frame)
@@ -3064,7 +3099,7 @@ the global options and expect it to be applied to the entire view.")
       ;; additional test in case agenda is invoked from within agenda
       ;; buffer via elisp link
       (unless (equal (current-buffer) abuf)
-       (switch-to-buffer abuf)))
+       (org-pop-to-buffer-same-window abuf)))
     (setq buffer-read-only nil)
     (let ((inhibit-read-only t)) (erase-buffer))
     (org-agenda-mode)
@@ -3178,17 +3213,9 @@ the global options and expect it to be applied to the entire view.")
        (setq org-blocked-by-checkboxes nil invis1 invis)
        (let ((marker (org-get-at-bol 'org-hd-marker)))
          (when (and marker
-                    (not (with-current-buffer (marker-buffer marker)
-                           (save-excursion
-                             (goto-char marker)
-                             (if (org-entry-get nil "NOBLOCKING")
-                                 t ;; Never block this entry
-                               (run-hook-with-args-until-failure
-                                'org-blocker-hook
-                                (list :type 'todo-state-change
-                                      :position marker
-                                      :from 'todo
-                                      :to 'done)))))))
+                    (with-current-buffer (marker-buffer marker)
+                      (save-excursion (goto-char marker)
+                                      (org-entry-blocked-p))))
            (if org-blocked-by-checkboxes (setq invis1 nil))
            (setq b (if invis1
                        (max (point-min) (1- (point-at-bol)))
@@ -3322,7 +3349,7 @@ no longer in use."
 
 (defvar org-agenda-only-exact-dates nil) ; dynamically scoped
 
-(defun org-timeline (&optional include-all)
+(defun org-timeline (&optional dotodo)
   "Show a time-sorted view of the entries in the current org file.
 Only entries with a time stamp of today or later will be listed.  With
 \\[universal-argument] prefix, all unfinished TODO items will also be shown,
@@ -3333,7 +3360,6 @@ dates."
   (org-compile-prefix-format 'timeline)
   (org-set-sorting-strategy 'timeline)
   (let* ((dopast t)
-        (dotodo include-all)
         (doclosed org-agenda-show-log)
         (entry (buffer-file-name (or (buffer-base-buffer (current-buffer))
                                      (current-buffer))))
@@ -3352,7 +3378,7 @@ dates."
     (setq org-agenda-redo-command
          (list 'progn
                (list 'org-switch-to-buffer-other-window (current-buffer))
-               (list 'org-timeline (list 'quote include-all))))
+               (list 'org-timeline (list 'quote dotodo))))
     (if (not dopast)
        ;; Remove past dates from the list of dates.
        (setq day-numbers (delq nil (mapcar (lambda(x)
@@ -3420,22 +3446,26 @@ When EMPTY is non-nil, also include days without any entries."
   (let ((re (concat
             (if pre-re pre-re "")
             (if inactive org-ts-regexp-both org-ts-regexp)))
-        dates dates1 date day day1 day2 ts1 ts2)
+        dates dates1 date day day1 day2 ts1 ts2 pos)
     (if force-today
        (setq dates (list (org-today))))
     (save-excursion
       (goto-char beg)
       (while (re-search-forward re end t)
        (setq day (time-to-days (org-time-string-to-time
-                                (substring (match-string 1) 0 10))))
+                                (substring (match-string 1) 0 10)
+                                (current-buffer) (match-beginning 0))))
        (or (memq day dates) (push day dates)))
       (unless no-ranges
        (goto-char beg)
        (while (re-search-forward org-tr-regexp end t)
+         (setq pos (match-beginning 0))
          (setq ts1 (substring (match-string 1) 0 10)
                ts2 (substring (match-string 2) 0 10)
-               day1 (time-to-days (org-time-string-to-time ts1))
-               day2 (time-to-days (org-time-string-to-time ts2)))
+               day1 (time-to-days (org-time-string-to-time
+                                   ts1 (current-buffer) pos))
+               day2 (time-to-days (org-time-string-to-time
+                                   ts2  (current-buffer) pos)))
          (while (< (setq day1 (1+ day1)) day2)
            (or (memq day1 dates) (push day1 dates)))))
       (setq dates (sort dates '<))
@@ -3460,7 +3490,7 @@ Custom commands can set this variable in the options section.")
 (defvar org-starting-day nil) ; local variable in the agenda buffer
 (defvar org-agenda-current-span nil
   "The current span used in the agenda view.") ; local variable in the agenda buffer
-(defvar org-include-all-loc nil) ; local variable
+(defvar org-arg-loc nil) ; local variable
 
 (defvar org-agenda-entry-types '(:deadline :scheduled :timestamp :sexp)
   "List of types searched for when creating the daily/weekly agenda.
@@ -3489,36 +3519,36 @@ By default, all four types are turned on.
 
 Never set this variable globally using `setq', because then it
 will apply to all future agenda commands.  Instead, bind it with
-`let' to scope it dynamically into the the agenda-constructing
+`let' to scope it dynamically into the agenda-constructing
 command.  A good way to set it is through options in
 `org-agenda-custom-commands'.  For a more flexible (though
 somewhat less efficient) way of determining what is included in
 the daily/weekly agenda, see `org-agenda-skip-function'.")
 
 ;;;###autoload
-(defun org-agenda-list (&optional include-all start-day span)
+(defun org-agenda-list (&optional arg start-day span)
   "Produce a daily/weekly view from all files in variable `org-agenda-files'.
 The view will be for the current day or week, but from the overview buffer
 you will be able to go to other days/weeks.
 
 With a numeric prefix argument in an interactive call, the agenda will
-span INCLUDE-ALL days.  Lisp programs should instead specify SPAN to change
+span ARG days.  Lisp programs should instead specify SPAN to change
 the number of days.  SPAN defaults to `org-agenda-span'.
 
 START-DAY defaults to TODAY, or to the most recent match for the weekday
 given in `org-agenda-start-on-weekday'."
   (interactive "P")
-  (if (and (integerp include-all) (> include-all 0))
-      (setq span include-all include-all nil))
+  (if (and (integerp arg) (> arg 0))
+      (setq span arg arg nil))
   (setq start-day (or start-day org-agenda-start-day))
   (if org-agenda-overriding-arguments
-      (setq include-all (car org-agenda-overriding-arguments)
+      (setq arg (car org-agenda-overriding-arguments)
            start-day (nth 1 org-agenda-overriding-arguments)
            span (nth 2 org-agenda-overriding-arguments)))
   (if (stringp start-day)
       ;; Convert to an absolute day number
       (setq start-day (time-to-days (org-read-date nil t start-day))))
-  (setq org-agenda-last-arguments (list include-all start-day span))
+  (setq org-agenda-last-arguments (list arg start-day span))
   (org-compile-prefix-format 'agenda)
   (org-set-sorting-strategy 'agenda)
   (let* ((span (org-agenda-ndays-to-span
@@ -3545,7 +3575,7 @@ given in `org-agenda-start-on-weekday'."
         s e rtn rtnall file date d start-pos end-pos todayp
         clocktable-start clocktable-end filter)
     (setq org-agenda-redo-command
-         (list 'org-agenda-list (list 'quote include-all) start-day (list 'quote span)))
+         (list 'org-agenda-list (list 'quote arg) start-day (list 'quote span)))
     (dotimes (n (1- ndays))
       (push (1+ (car day-numbers)) day-numbers))
     (setq day-numbers (nreverse day-numbers))
@@ -3553,7 +3583,7 @@ given in `org-agenda-start-on-weekday'."
          clocktable-end (1+ (or (org-last day-numbers) 0)))
     (org-prepare-agenda "Day/Week")
     (org-set-local 'org-starting-day (car day-numbers))
-    (org-set-local 'org-include-all-loc include-all)
+    (org-set-local 'org-arg-loc arg)
     (org-set-local 'org-agenda-current-span (org-agenda-ndays-to-span span))
     (unless org-agenda-compact-blocks
       (let* ((d1 (car day-numbers))
@@ -3774,7 +3804,7 @@ in `org-agenda-text-search-extra-files'."
         (full-words org-agenda-search-view-force-full-words)
         (org-agenda-text-search-extra-files org-agenda-text-search-extra-files)
         regexp rtn rtnall files file pos
-        marker category tags c neg re boolean
+        marker category category-pos tags c neg re boolean
         ee txt beg end words regexps+ regexps- hdl-only buffer beg1 str)
     (unless (and (not edit-at)
                 (stringp string)
@@ -3855,7 +3885,7 @@ in `org-agenda-text-search-extra-files'."
            regexps+))
     (setq regexps+ (sort regexps+ (lambda (a b) (> (length a) (length b)))))
     (if (not regexps+)
-       (setq regexp (concat "^" org-outline-regexp))
+       (setq regexp org-outline-regexp-bol)
       (setq regexp (pop regexps+))
       (if hdl-only (setq regexp (concat "^" org-outline-regexp ".*?"
                                        regexp))))
@@ -3878,7 +3908,7 @@ in `org-agenda-text-search-extra-files'."
                                    file))))
        (with-current-buffer buffer
          (with-syntax-table (org-search-syntax-table)
-           (unless (org-mode-p)
+           (unless (eq major-mode 'org-mode)
              (error "Agenda file %s is not in `org-mode'" file))
            (let ((case-fold-search t))
              (save-excursion
@@ -3918,6 +3948,7 @@ in `org-agenda-text-search-extra-files'."
                      (goto-char beg)
                      (setq marker (org-agenda-new-marker (point))
                            category (org-get-category)
+                           category-pos (get-text-property (point) 'org-category-position)
                            tags (org-get-tags-at (point))
                            txt (org-format-agenda-item
                                 ""
@@ -3929,6 +3960,7 @@ in `org-agenda-text-search-extra-files'."
                        'org-todo-regexp org-todo-regexp
                        'org-complex-heading-regexp org-complex-heading-regexp
                        'priority 1000 'org-category category
+                       'org-category-position category-pos
                        'type "search")
                      (push txt ee)
                      (goto-char (1- end))))))))))
@@ -4069,7 +4101,7 @@ The prefix arg TODO-ONLY limits the search to TODO entries."
                       (format "ORG-AGENDA-ERROR: No such org-file %s" file))
                  rtnall (append rtnall rtn))
          (with-current-buffer buffer
-           (unless (org-mode-p)
+           (unless (eq major-mode 'org-mode)
              (error "Agenda file %s is not in `org-mode'" file))
            (save-excursion
              (save-restriction
@@ -4111,7 +4143,7 @@ This is basically a temporary global variable that can be set and then
 used by user-defined selections using `org-agenda-skip-function'.")
 
 (defvar org-agenda-overriding-header nil
-  "When this is set during todo and tags searches, will replace header.
+  "When set during agenda, todo and tags searches it replaces the header.
 This variable should not be set directly, but custom commands can bind it
 in the options section.")
 
@@ -4293,9 +4325,11 @@ of what a project is and how to check if it stuck, customize the variable
                          "\\)\\>"))
         (tags (nth 2 org-stuck-projects))
         (tags-re (if (member "*" tags)
-                     (org-re "^\\*+ .*:[[:alnum:]_@#%]+:[ \t]*$")
+                     (concat org-outline-regexp-bol
+                             (org-re ".*:[[:alnum:]_@#%]+:[ \t]*$"))
                    (if tags
-                       (concat "^\\*+ .*:\\("
+                       (concat org-outline-regexp-bol
+                               ".*:\\("
                                (mapconcat 'identity tags "\\|")
                                (org-re "\\):[[:alnum:]_@#%:]*[ \t]*$")))))
         (gen-re (nth 3 org-stuck-projects))
@@ -4511,7 +4545,7 @@ the documentation of `org-diary'."
        ;; If file does not exist, make sure an error message ends up in diary
        (list (format "ORG-AGENDA-ERROR: No such org-file %s" file))
       (with-current-buffer buffer
-       (unless (org-mode-p)
+       (unless (eq major-mode 'org-mode)
          (error "Agenda file %s is not in `org-mode'" file))
        (let ((case-fold-search nil))
          (save-excursion
@@ -4564,12 +4598,13 @@ the documentation of `org-diary'."
                             (if (equal org-select-this-todo-keyword "*")
                                 org-todo-regexp
                               (concat "\\<\\("
-                                      (mapconcat 'identity (org-split-string org-select-this-todo-keyword "|") "\\|")
+                                      (mapconcat 'identity
+                                                 (org-split-string
+                                                  org-select-this-todo-keyword "|") "\\|")
                                     "\\)\\>"))
                           org-not-done-regexp)
                         "[^\n\r]*\\)"))
-        marker priority category tags todo-state
-        ee txt beg end)
+        marker priority category category-pos tags todo-state ee txt beg end)
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (catch :skip
@@ -4584,6 +4619,7 @@ the documentation of `org-diary'."
        (goto-char (match-beginning 1))
        (setq marker (org-agenda-new-marker (match-beginning 0))
              category (org-get-category)
+             category-pos (get-text-property (point) 'org-category-position)
              txt (match-string 1)
              tags (org-get-tags-at (point))
              txt (org-format-agenda-item "" txt category tags)
@@ -4592,6 +4628,7 @@ the documentation of `org-diary'."
        (org-add-props txt props
          'org-marker marker 'org-hd-marker marker
          'priority priority 'org-category category
+         'org-category-position category-pos
          'type "todo" 'todo-state todo-state)
        (push txt ee)
        (if org-agenda-todo-list-sublevels
@@ -4706,8 +4743,8 @@ This function is invoked if `org-agenda-todo-ignore-deadlines',
           "\\|\\(<[0-9]+-[0-9]+-[0-9]+[^>\n]+?\\+[0-9]+[dwmy]>\\)"
           "\\|\\(<%%\\(([^>\n]+)\\)>\\)"))
         marker hdmarker deadlinep scheduledp clockp closedp inactivep
-        donep tmp priority category ee txt timestr tags b0 b3 e3 head
-        todo-state end-of-match show-all)
+        donep tmp priority category category-pos ee txt timestr tags
+        b0 b3 e3 head todo-state end-of-match show-all)
     (goto-char (point-min))
     (while (setq end-of-match (re-search-forward regexp nil t))
       (setq b0 (match-beginning 0)
@@ -4721,7 +4758,8 @@ This function is invoked if `org-agenda-todo-ignore-deadlines',
        (org-agenda-skip)
        (if (and (match-end 1)
                 (not (= d1 (org-time-string-to-absolute
-                            (match-string 1) d1 nil show-all))))
+                            (match-string 1) d1 nil show-all
+                            (current-buffer) b0))))
            (throw :skip nil))
        (if (and e3
                 (not (org-diary-sexp-entry (buffer-substring b3 e3) "" date)))
@@ -4746,9 +4784,10 @@ This function is invoked if `org-agenda-todo-ignore-deadlines',
            ;; substring should only run to end of time stamp
            (setq timestr (substring timestr 0 (match-end 0))))
        (setq marker (org-agenda-new-marker b0)
-             category (org-get-category b0))
+             category (org-get-category b0)
+             category-pos (get-text-property b0 'org-category-position))
        (save-excursion
-         (if (not (re-search-backward "^\\*+ " nil t))
+         (if (not (re-search-backward org-outline-regexp-bol nil t))
              (setq txt org-agenda-no-heading-message)
            (goto-char (match-beginning 0))
            (setq hdmarker (org-agenda-new-marker)
@@ -4764,6 +4803,7 @@ This function is invoked if `org-agenda-todo-ignore-deadlines',
            'org-marker marker 'org-hd-marker hdmarker)
          (org-add-props txt nil 'priority priority
                         'org-category category 'date date
+                        'org-category-position category-pos
                         'todo-state todo-state
                         'type "timestamp")
          (push txt ee))
@@ -4780,8 +4820,8 @@ This function is invoked if `org-agenda-todo-ignore-deadlines',
                      (format "mouse-2 or RET jump to org file %s"
                              (abbreviate-file-name buffer-file-name))))
         (regexp "^&?%%(")
-        marker category ee txt tags entry result beg b sexp sexp-entry
-        todo-state)
+        marker category category-pos ee txt tags entry
+        result beg b sexp sexp-entry todo-state)
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (catch :skip
@@ -4798,6 +4838,7 @@ This function is invoked if `org-agenda-todo-ignore-deadlines',
        (when result
          (setq marker (org-agenda-new-marker beg)
                category (org-get-category beg)
+               category-pos (get-text-property beg 'org-category-position)
                todo-state (org-get-todo-state))
 
          (dolist (r (if (stringp result)
@@ -4812,23 +4853,46 @@ This function is invoked if `org-agenda-todo-ignore-deadlines',
            (org-add-props txt props 'org-marker marker)
            (org-add-props txt nil
              'org-category category 'date date 'todo-state todo-state
+             'org-category-position category-pos
              'type "sexp")
            (push txt ee)))))
     (nreverse ee)))
 
-(defun org-diary-class (m1 d1 y1 m2 d2 y2 dayname &rest skip-weeks)
+;; Calendar sanity: define some functions that are independent of
+;; `calendar-date-style'.
+;; Normally I would like to use ISO format when calling the diary functions,
+;; but to make sure we still have Emacs 22 compatibility we bind
+;; also `european-calendar-style' and use european format
+(defun org-anniversary (year month day &optional mark)
+  "Like `diary-anniversary', but with fixed (ISO) order of arguments."
+  (org-no-warnings
+   (let ((calendar-date-style 'european) (european-calendar-style t))
+     (diary-anniversary day month year mark))))
+(defun org-cyclic (N year month day &optional mark)
+  "Like `diary-cyclic', but with fixed (ISO) order of arguments."
+  (org-no-warnings
+   (let ((calendar-date-style 'european)       (european-calendar-style t))
+     (diary-cyclic N day month year mark))))
+(defun org-block (Y1 M1 D1 Y2 M2 D2 &optional mark)
+  "Like `diary-block', but with fixed (ISO) order of arguments."
+  (org-no-warnings
+   (let ((calendar-date-style 'european)       (european-calendar-style t))
+     (diary-block D1 M1 Y1 D2 M2 Y2 mark))))
+(defun org-date (year month day &optional mark)
+  "Like `diary-date', but with fixed (ISO) order of arguments."
+  (org-no-warnings
+   (let ((calendar-date-style 'european)       (european-calendar-style t))
+     (diary-date day month year mark))))
+(defalias 'org-float 'diary-float)
+
+;; Define the` org-class' function
+(defun org-class (y1 m1 d1 y2 m2 d2 dayname &rest skip-weeks)
   "Entry applies if date is between dates on DAYNAME, but skips SKIP-WEEKS.
-The order of the first 2 times 3 arguments depends on the variable
-`calendar-date-style' or, if that is not defined, on `european-calendar-style'.
-So for American calendars, give this as MONTH DAY YEAR, for European as
-DAY MONTH YEAR, and for ISO as YEAR MONTH DAY.
 DAYNAME is a number between 0 (Sunday) and 6 (Saturday).  SKIP-WEEKS
 is any number of ISO weeks in the block period for which the item should
 be skipped."
-  (let* ((date1 (calendar-absolute-from-gregorian
-                (org-order-calendar-date-args m1 d1 y1)))
-        (date2 (calendar-absolute-from-gregorian
-                (org-order-calendar-date-args m2 d2 y2)))
+  (let* ((date1 (calendar-absolute-from-gregorian (list m1 d1 y1)))
+        (date2 (calendar-absolute-from-gregorian (list m2 d2 y2)))
         (d (calendar-absolute-from-gregorian date)))
     (and
      (<= date1 d)
@@ -4840,6 +4904,25 @@ be skipped."
           (not (member (car (calendar-iso-from-absolute d)) skip-weeks))))
      entry)))
 
+(defun org-diary-class (m1 d1 y1 m2 d2 y2 dayname &rest skip-weeks)
+  "Like `org-class', but honor `calendar-date-style'.
+The order of the first 2 times 3 arguments depends on the variable
+`calendar-date-style' or, if that is not defined, on `european-calendar-style'.
+So for American calendars, give this as MONTH DAY YEAR, for European as
+DAY MONTH YEAR, and for ISO as YEAR MONTH DAY.
+DAYNAME is a number between 0 (Sunday) and 6 (Saturday).  SKIP-WEEKS
+is any number of ISO weeks in the block period for which the item should
+be skipped.
+
+This function is here only for backward compatibility and it is deprecated,
+please use `org-class' instead."
+  (let* ((date1 (org-order-calendar-date-args m1 d1 y1))
+        (date2 (org-order-calendar-date-args m2 d2 y2)))
+    (org-class
+     (nth 2 date1) (car date1) (nth 1 date1)
+     (nth 2 date2) (car date2) (nth 1 date2)
+     dayname skip-weeks)))
+
 (defalias 'org-get-closed 'org-agenda-get-progress)
 (defun org-agenda-get-progress ()
   "Return the logged TODO entries for agenda display."
@@ -4874,8 +4957,8 @@ be skipped."
                            (list 0 0 0 (nth 1 date) (car date) (nth 2 date))))
                    1 11))))
         (org-agenda-search-headline-for-time nil)
-        marker hdmarker priority category tags closedp statep clockp state
-        ee txt extra timestr rest clocked)
+        marker hdmarker priority category category-pos tags closedp
+        statep clockp state ee txt extra timestr rest clocked)
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (catch :skip
@@ -4886,14 +4969,15 @@ be skipped."
              clockp (not (or closedp statep))
              state (and statep (match-string 2))
              category (org-get-category (match-beginning 0))
-             timestr (buffer-substring (match-beginning 0) (point-at-eol))
-             )
+             category-pos (get-text-property (match-beginning 0) 'org-category-position)
+             timestr (buffer-substring (match-beginning 0) (point-at-eol)))
        (when (string-match "\\]" timestr)
          ;; substring should only run to end of time stamp
          (setq rest (substring timestr (match-end 0))
                timestr (substring timestr 0 (match-end 0)))
          (if (and (not closedp) (not statep)
-                  (string-match "\\([0-9]\\{1,2\\}:[0-9]\\{2\\}\\)\\].*?\\([0-9]\\{1,2\\}:[0-9]\\{2\\}\\)" rest))
+                  (string-match "\\([0-9]\\{1,2\\}:[0-9]\\{2\\}\\)\\].*?\\([0-9]\\{1,2\\}:[0-9]\\{2\\}\\)"
+                                rest))
              (progn (setq timestr (concat (substring timestr 0 -1)
                                           "-" (match-string 1 rest) "]"))
                     (setq clocked (match-string 2 rest)))
@@ -4908,7 +4992,7 @@ be skipped."
                 (clockp
                  (and (looking-at ".*\n[ \t]*-[ \t]+\\([^-\n \t].*?\\)[ \t]*$")
                       (match-string 1)))))
-         (if (not (re-search-backward "^\\*+ " nil t))
+         (if (not (re-search-backward org-outline-regexp-bol nil t))
              (setq txt org-agenda-no-heading-message)
            (goto-char (match-beginning 0))
            (setq hdmarker (org-agenda-new-marker)
@@ -4930,6 +5014,7 @@ be skipped."
          (org-add-props txt props
            'org-marker marker 'org-hd-marker hdmarker 'face 'org-agenda-done
            'priority priority 'org-category category
+           'org-category-position category-pos
            'type "closed" 'date date
            'undone-face 'org-warning 'done-face 'org-agenda-done)
          (push txt ee))
@@ -4948,9 +5033,9 @@ See also the user option `org-agenda-clock-consistency-checks'."
                     "\\(-\\{1,3\\}\\(\\[.*?\\]\\)\\)?")) ; group 3 is second
         (tlstart 0.)
         (tlend 0.)
-        (maxtime (org-hh:mm-string-to-minutes 
+        (maxtime (org-hh:mm-string-to-minutes
                   (or (plist-get pl :max-duration) "24:00")))
-        (mintime (org-hh:mm-string-to-minutes 
+        (mintime (org-hh:mm-string-to-minutes
                   (or (plist-get pl :min-duration) 0)))
         (maxgap  (org-hh:mm-string-to-minutes
                   ;; default 30:00 means never complain
@@ -5067,9 +5152,9 @@ See also the user option `org-agenda-clock-consistency-checks'."
         (regexp org-deadline-time-regexp)
         (todayp (org-agenda-todayp date)) ; DATE bound by calendar
         (d1 (calendar-absolute-from-gregorian date))  ; DATE bound by calendar
-        d2 diff dfrac wdays pos pos1 category tags
-        suppress-prewarning
-        ee txt head face s todo-state show-all upcomingp donep timestr)
+        d2 diff dfrac wdays pos pos1 category category-pos
+        tags suppress-prewarning ee txt head face s todo-state
+        show-all upcomingp donep timestr)
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (setq suppress-prewarning nil)
@@ -5092,13 +5177,14 @@ See also the user option `org-agenda-clock-consistency-checks'."
                           (member todo-state
                                    org-agenda-repeating-timestamp-show-all))
              d2 (org-time-string-to-absolute
-                 (match-string 1) d1 'past show-all)
+                 (match-string 1) d1 'past show-all
+                 (current-buffer) pos)
              diff (- d2 d1)
              wdays (if suppress-prewarning
                        (let ((org-deadline-warning-days suppress-prewarning))
                          (org-get-wdays s))
                      (org-get-wdays s))
-             dfrac (/ (* 1.0 (- wdays diff)) (max wdays 1))
+             dfrac (- 1 (/ (* 1.0 diff) (max wdays 1)))
              upcomingp (and todayp (> diff 0)))
        ;; When to show a deadline in the calendar:
        ;; If the expiration is within wdays warning time.
@@ -5113,7 +5199,8 @@ See also the user option `org-agenda-clock-consistency-checks'."
                       (or org-agenda-skip-deadline-if-done
                           (not (= diff 0))))
                  (setq txt nil)
-               (setq category (org-get-category))
+               (setq category (org-get-category)
+                     category-pos (get-text-property (point) 'org-category-position))
                (if (not (re-search-backward "^\\*+[ \t]+" nil t))
                    (setq txt org-agenda-no-heading-message)
                  (goto-char (match-end 0))
@@ -5140,13 +5227,14 @@ See also the user option `org-agenda-clock-consistency-checks'."
                             head category tags
                             (if (not (= diff 0)) nil timestr)))))
              (when txt
-               (setq face (org-agenda-deadline-face dfrac wdays))
+               (setq face (org-agenda-deadline-face dfrac))
                (org-add-props txt props
                  'org-marker (org-agenda-new-marker pos)
                  'org-hd-marker (org-agenda-new-marker pos1)
                  'priority (+ (- diff)
                               (org-get-priority txt))
                  'org-category category
+                 'org-category-position category-pos
                  'todo-state todo-state
                  'type (if upcomingp "upcoming-deadline" "deadline")
                  'date (if upcomingp date d2)
@@ -5155,10 +5243,9 @@ See also the user option `org-agenda-clock-consistency-checks'."
                (push txt ee))))))
     (nreverse ee)))
 
-(defun org-agenda-deadline-face (fraction &optional wdays)
+(defun org-agenda-deadline-face (fraction)
   "Return the face to displaying a deadline item.
 FRACTION is what fraction of the head-warning time has passed."
-  (if (equal wdays 0) (setq fraction 1.))
   (let ((faces org-agenda-deadline-faces) f)
     (catch 'exit
       (while (setq f (pop faces))
@@ -5183,7 +5270,7 @@ FRACTION is what fraction of the head-warning time has passed."
                                        0 'org-hd-marker a))
                              (cons (marker-position mm) a)))
                  deadline-results))
-        d2 diff pos pos1 category tags donep
+        d2 diff pos pos1 category category-pos tags donep
         ee txt head pastschedp todo-state face timestr s habitp show-all)
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
@@ -5197,7 +5284,8 @@ FRACTION is what fraction of the head-warning time has passed."
                           (member todo-state
                                   org-agenda-repeating-timestamp-show-all))
              d2 (org-time-string-to-absolute
-                 (match-string 1) d1 'past show-all)
+                 (match-string 1) d1 'past show-all
+                 (current-buffer) pos)
              diff (- d2 d1))
        (setq pastschedp (and todayp (< diff 0)))
        ;; When to show a scheduled item in the calendar:
@@ -5216,7 +5304,8 @@ FRACTION is what fraction of the head-warning time has passed."
                (setq txt nil)
              (setq habitp (and (functionp 'org-is-habit-p)
                                (org-is-habit-p)))
-             (setq category (org-get-category))
+             (setq category (org-get-category)
+                   category-pos (get-text-property (point) 'org-category-position))
              (if (not (re-search-backward "^\\*+[ \t]+" nil t))
                  (setq txt org-agenda-no-heading-message)
                (goto-char (match-end 0))
@@ -5267,6 +5356,7 @@ FRACTION is what fraction of the head-warning time has passed."
                              (org-habit-get-priority habitp)
                            (+ 94 (- 5 diff) (org-get-priority txt)))
                'org-category category
+               'org-category-position category-pos
                'org-habit-p habitp
                'todo-state todo-state)
              (push txt ee))))))
@@ -5295,8 +5385,8 @@ FRACTION is what fraction of the head-warning time has passed."
              (end-time (match-string 2)))
          (setq s1 (match-string 1)
                s2 (match-string 2)
-               d1 (time-to-days (org-time-string-to-time s1))
-               d2 (time-to-days (org-time-string-to-time s2)))
+               d1 (time-to-days (org-time-string-to-time s1 (current-buffer) pos))
+               d2 (time-to-days (org-time-string-to-time s2 (current-buffer) pos)))
          (if (and (> (- d0 d1) -1) (> (- d2 d0) -1))
              ;; Only allow days between the limits, because the normal
              ;; date stamps will catch the limits.
@@ -5306,8 +5396,9 @@ FRACTION is what fraction of the head-warning time has passed."
                (if (and donep org-agenda-skip-timestamp-if-done)
                    (throw :skip t))
                (setq marker (org-agenda-new-marker (point)))
-               (setq category (org-get-category))
-               (if (not (re-search-backward "^\\*+ " nil t))
+               (setq category (org-get-category)
+                     category-pos (get-text-property (point) 'org-category-position))
+               (if (not (re-search-backward org-outline-regexp-bol nil t))
                    (setq txt org-agenda-no-heading-message)
                  (goto-char (match-beginning 0))
                  (setq hdmarker (org-agenda-new-marker (point)))
@@ -5327,7 +5418,9 @@ FRACTION is what fraction of the head-warning time has passed."
                                     org-agenda-timerange-leaders)
                                (1+ (- d0 d1)) (1+ (- d2 d1)))
                               head category tags
-                              (cond ((= d1 d0)
+                              (cond ((and (= d1 d0) (= d2 d0))
+                                     (concat "<" start-time ">--<" end-time ">"))
+                                     ((= d1 d0)
                                      (concat "<" start-time ">"))
                                     ((= d2 d0)
                                      (concat "<" end-time ">"))
@@ -5337,7 +5430,8 @@ FRACTION is what fraction of the head-warning time has passed."
                  'org-marker marker 'org-hd-marker hdmarker
                  'type "block" 'date date
                  'todo-state todo-state
-                 'priority (org-get-priority txt) 'org-category category)
+                 'priority (org-get-priority txt) 'org-category category
+                 'org-category-position category-pos)
                (push txt ee))))
        (goto-char pos)))
     ;; Sort the entries by expiration date.
@@ -5409,7 +5503,7 @@ Any match of REMOVE-RE will be removed from TXT."
           (time-of-day (and dotime (org-get-time-of-day ts)))
           stamp plain s0 s1 s2 rtn srp l
           duration thecategory)
-      (and (org-mode-p) buffer-file-name
+      (and (eq major-mode 'org-mode) buffer-file-name
           (add-to-list 'org-agenda-contributing-files buffer-file-name))
       (when (and dotime time-of-day)
        ;; Extract starting and ending time and move them to prefix
@@ -5457,7 +5551,7 @@ Any match of REMOVE-RE will be removed from TXT."
                     (concat (make-string (max (- 50 (length txt)) 1) ?\ )
                             (match-string 2 txt))
                     t t txt))))
-      (when (org-mode-p)
+      (when (eq major-mode 'org-mode)
        (setq effort
              (condition-case nil
                  (org-get-effort
@@ -5466,7 +5560,9 @@ Any match of REMOVE-RE will be removed from TXT."
                (error nil)))
        (when effort
          (setq neffort (org-duration-string-to-minutes effort)
-               effort (setq effort (concat "[" effort "]" )))))
+               effort (setq effort (concat "[" effort "]")))))
+      ;; prevent erroring out with %e format when there is no effort
+      (or effort (setq effort ""))
 
       (when remove-re
        (while (string-match remove-re txt)
@@ -5520,6 +5616,7 @@ Any match of REMOVE-RE will be removed from TXT."
        'txt txt
        'time time
        'extra extra
+       'format org-prefix-format-compiled
        'dotime dotime))))
 
 (defun org-agenda-fix-displayed-tags (txt tags add-inherited hide-re)
@@ -5609,7 +5706,8 @@ The modified list may contain inherited tags, and tags matched by
 The resulting form is returned and stored in the variable
 `org-prefix-format-compiled'."
   (setq org-prefix-has-time nil org-prefix-has-tag nil
-       org-prefix-category-length nil  org-prefix-has-effort nil)
+       org-prefix-category-length nil
+       org-prefix-has-effort nil)
   (let ((s (cond
            ((stringp org-agenda-prefix-format)
             org-agenda-prefix-format)
@@ -5760,7 +5858,7 @@ could bind the variable in the options section of a custom command.")
          (t nil))))
 
 (defsubst org-cmp-effort (a b)
-  "Compare the priorities of string A and B."
+  "Compare the effort values of string A and B."
   (let* ((def (if org-sort-agenda-noeffort-is-high 32767 -1))
         (ea (or (get-text-property 1 'effort-minutes a) def))
         (eb (or (get-text-property 1 'effort-minutes b) def)))
@@ -6039,7 +6137,7 @@ When this is the global TODO list, a prefix argument will be interpreted."
     (message "Rebuilding agenda buffer...done")
     (put 'org-agenda-filter :preset-filter preset)
     (and (or filter preset) (org-agenda-filter-apply filter))
-    (and cols (called-interactively-p 'any) (org-agenda-columns))
+    (and cols (org-called-interactively-p 'any) (org-agenda-columns))
     (org-goto-line line)
     (recenter window-line)))
 
@@ -6157,7 +6255,7 @@ to switch to narrowing."
     tags))
 
 (defun org-agenda-filter-by-tag-refine (strip &optional char)
-  "Refine the current filter.  See `org-agenda-filter-by-tag."
+  "Refine the current filter.  See `org-agenda-filter-by-tag'."
   (interactive "P")
   (org-agenda-filter-by-tag strip char 'refine))
 
@@ -6534,8 +6632,7 @@ so that the date SD will be in that range."
   (interactive)
   (setq org-agenda-follow-mode (not org-agenda-follow-mode))
   (org-agenda-set-mode-name)
-  (if (and org-agenda-follow-mode (org-get-at-bol 'org-marker))
-      (org-agenda-show))
+  (org-agenda-do-context-action)
   (message "Follow mode is %s"
           (if org-agenda-follow-mode "on" "off")))
 
@@ -6696,11 +6793,13 @@ When called with a prefix argument, include all archive files as well."
 (defun org-agenda-do-context-action ()
   "Show outline path and, maybe, follow mode window."
   (let ((m (org-get-at-bol 'org-marker)))
-    (if (and org-agenda-follow-mode m)
-       (org-agenda-show))
-    (if (and m org-agenda-show-outline-path)
-       (org-with-point-at m
-         (org-display-outline-path t)))))
+    (when (and (markerp m) (marker-buffer m))
+      (and org-agenda-follow-mode
+          (if org-agenda-follow-indirect
+              (org-agenda-tree-to-indirect-buffer)
+            (org-agenda-show)))
+      (and org-agenda-show-outline-path
+          (org-with-point-at m (org-display-outline-path t))))))
 
 (defun org-agenda-show-priority ()
   "Show the priority of the current item.
@@ -6730,7 +6829,7 @@ and by additional input from the age of a schedules or deadline entry."
     (widen)
     (push-mark)
     (goto-char pos)
-    (when (org-mode-p)
+    (when (eq major-mode 'org-mode)
       (org-show-context 'agenda)
       (save-excursion
        (and (outline-next-heading)
@@ -6759,7 +6858,7 @@ Point is in the buffer where the item originated.")
      (with-current-buffer buffer
        (save-excursion
         (goto-char pos)
-        (if (and (org-mode-p) (not (member type '("sexp"))))
+        (if (and (eq major-mode 'org-mode) (not (member type '("sexp"))))
             (setq dbeg (progn (org-back-to-heading t) (point))
                   dend (org-end-of-subtree t t))
           (setq dbeg (point-at-bol)
@@ -6811,7 +6910,7 @@ Point is in the buffer where the item originated.")
         (pos (marker-position marker)))
     (org-with-remote-undo buffer
       (with-current-buffer buffer
-       (if (org-mode-p)
+       (if (eq major-mode 'org-mode)
            (if (and confirm
                     (not (y-or-n-p "Archive this subtree or entry? ")))
                (error "Abort")
@@ -6912,11 +7011,11 @@ at the text of the entry itself."
                       (org-agenda-error)))
           (buffer (marker-buffer marker))
           (pos (marker-position marker)))
-      (switch-to-buffer buffer)
+      (org-pop-to-buffer-same-window buffer)
       (and delete-other-windows (delete-other-windows))
       (widen)
       (goto-char pos)
-      (when (org-mode-p)
+      (when (eq major-mode 'org-mode)
        (org-show-context 'agenda)
        (save-excursion
          (and (outline-next-heading)
@@ -6990,7 +7089,7 @@ if it was hidden in the outline."
        (org-back-to-heading)
        (run-hook-with-args 'org-cycle-hook 'folded))
       (message "Remote: FOLDED"))
-     ((and (called-interactively-p 'any) (= more 1))
+     ((and (org-called-interactively-p 'any) (= more 1))
       (message "Remote: show with default settings"))
      ((= more 2)
       (show-entry)
@@ -7194,8 +7293,16 @@ If FORCE-TAGS is non nil, the car of it returns the new tags."
                dotime (org-get-at-bol 'dotime)
                cat (org-get-at-bol 'org-category)
                tags thetags
-               new (org-format-agenda-item (org-get-at-bol 'extra)
-                                           newhead cat tags dotime)
+               new
+               (let ((org-prefix-format-compiled
+                      (or (get-text-property (point) 'format)
+                          org-prefix-format-compiled)))
+                 (with-current-buffer (marker-buffer hdmarker)
+                   (save-excursion
+                     (save-restriction
+                       (widen)
+                       (org-format-agenda-item (org-get-at-bol 'extra)
+                                               newhead cat 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))
@@ -7291,7 +7398,7 @@ the same tree node, and the headline of the tree node in the Org-mode file."
   "Set tags for the current headline."
   (interactive)
   (org-agenda-check-no-diary)
-  (if (and (org-region-active-p) (called-interactively-p 'any))
+  (if (and (org-region-active-p) (org-called-interactively-p 'any))
       (call-interactively 'org-change-tag-in-region)
     (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
                         (org-agenda-error)))
@@ -7357,10 +7464,12 @@ the same tree node, and the headline of the tree node in the Org-mode file."
          (org-show-context 'agenda))
        (save-excursion
          (and (outline-next-heading)
-              (org-flag-heading nil)))   ; show the next heading
+              (org-flag-heading nil))) ; show the next heading
        (goto-char pos)
        (call-interactively 'org-set-effort)
-       (end-of-line 1)))))
+       (end-of-line 1)
+       (setq newhead (org-get-heading)))
+      (org-agenda-change-all-lines newhead hdmarker))))
 
 (defun org-agenda-toggle-archive-tag ()
   "Toggle the archive tag for the current entry."
@@ -7426,15 +7535,33 @@ the same tree node, and the headline of the tree node in the Org-mode file."
   (let* ((marker (or (org-get-at-bol 'org-marker)
                     (org-agenda-error)))
         (buffer (marker-buffer marker))
-        (pos (marker-position marker)))
+        (pos (marker-position marker))
+        cdate today)
     (org-with-remote-undo buffer
-     (with-current-buffer buffer
-       (widen)
-       (goto-char pos)
-       (if (not (org-at-timestamp-p))
-          (error "Cannot find time stamp"))
-       (org-timestamp-change arg (or what 'day)))
-     (org-agenda-show-new-time marker org-last-changed-timestamp))
+      (with-current-buffer buffer
+       (widen)
+       (goto-char pos)
+       (if (not (org-at-timestamp-p))
+           (error "Cannot find time stamp"))
+       (when (and org-agenda-move-date-from-past-immediately-to-today
+                  (equal arg 1)
+                  (or (not what) (eq what 'day))
+                  (not (save-match-data (org-at-date-range-p))))
+         (setq cdate (org-parse-time-string (match-string 0) 'nodefault)
+               cdate (calendar-absolute-from-gregorian 
+                      (list (nth 4 cdate) (nth 3 cdate) (nth 5 cdate)))
+               today (org-today))
+         (if (> today cdate)
+             ;; immediately shift to today
+             (setq arg (- today cdate))))
+       (org-timestamp-change arg (or what 'day))
+       (when (and (org-at-date-range-p)
+                  (re-search-backward org-tr-regexp-both (point-at-bol)))
+         (let ((end org-last-changed-timestamp))
+           (org-timestamp-change arg (or what 'day))
+           (setq org-last-changed-timestamp
+                 (concat org-last-changed-timestamp "--" end)))))
+      (org-agenda-show-new-time marker org-last-changed-timestamp))
     (message "Time stamp changed to %s" org-last-changed-timestamp)))
 
 (defun org-agenda-date-earlier (arg &optional what)
@@ -7514,7 +7641,7 @@ be used to request time specification in the time stamp."
 
 (defun org-agenda-schedule (arg &optional time)
   "Schedule the item at point.
-Arg is passed through to `org-schedule'."
+ARG is passed through to `org-schedule'."
   (interactive "P")
   (org-agenda-check-type t 'agenda 'timeline 'todo 'tags 'search)
   (org-agenda-check-no-diary)
@@ -7536,7 +7663,7 @@ Arg is passed through to `org-schedule'."
 
 (defun org-agenda-deadline (arg &optional time)
   "Schedule the item at point.
-Arg is passed through to `org-deadline'."
+ARG is passed through to `org-deadline'."
   (interactive "P")
   (org-agenda-check-type t 'agenda 'timeline 'todo 'tags 'search)
   (org-agenda-check-no-diary)
@@ -7768,17 +7895,8 @@ the resulting entry will not be shown.  When TEXT is empty, switch to
       (org-back-over-empty-lines)
       (backward-char 1)
       (insert "\n")
-      (require 'diary-lib)
-      (let ((calendar-date-display-form
-            (if (if (boundp 'calendar-date-style)
-                    (eq calendar-date-style 'european)
-                  (with-no-warnings ;; european-calendar-style is obsolete as of version 23.1
-                    (org-bound-and-true-p european-calendar-style))) ; Emacs 22
-                '(day " " month " " year)
-              '(month " " day " " year))))
-
-       (insert (format "%%%%(diary-anniversary %s) %s"
-                       (calendar-date-string d1 nil t) text))))
+      (insert (format "%%%%(org-anniversary %d %2d %2d) %s"
+                     (nth 2 d1) (car d1) (nth 1 d1) text)))
      ((eq type 'day)
       (let ((org-prefix-has-time t)
            (org-agenda-time-leading-zero t)
@@ -8112,7 +8230,13 @@ The prefix arg is passed through to the command if possible."
    org-agenda-bulk-marked-entries)
 
   ;; Prompt for the bulk command
-  (message "Bulk: [r]efile [$]arch [A]rch->sib [t]odo [+/-]tag [s]chd [S]catter [d]eadline [f]unction")
+  (message (concat "Bulk: [r]efile [$]arch [A]rch->sib [t]odo"
+                  " [+/-]tag [s]chd [S]catter [d]eadline [f]unction"
+                  (when org-agenda-bulk-custom-functions
+                    (concat " Custom: ["
+                            (mapconcat (lambda(f) (char-to-string (car f)))
+                                       org-agenda-bulk-custom-functions "")
+                            "]"))))
   (let* ((action (read-char-exclusive))
         (org-log-refile (if org-log-refile 'time nil))
         (entries (reverse org-agenda-bulk-marked-entries))
@@ -8206,6 +8330,10 @@ The prefix arg is passed through to the command if possible."
                         (org-agenda-schedule nil time))
                     (error nil)))))))
 
+     ((assoc action org-agenda-bulk-custom-functions)
+      (setq cmd (list (cadr (assoc action org-agenda-bulk-custom-functions)))
+           redo-at-end t))
+
      ((equal action ?f)
       (setq cmd (list (intern
                       (org-icompleting-read "Function: "
@@ -8372,8 +8500,14 @@ belonging to the \"Work\" category."
                date)))
     (eq date today)))
 
-(provide 'org-agenda)
+(defun org-agenda-todo-yesterday (&optional arg)
+  "Like `org-agenda-todo' but the time of change will be 23:59 of yesterday"
+  (interactive "P")
+  (let* ((hour (third (decode-time
+                       (org-current-time))))
+         (org-extend-today-until (1+ hour)))
+    (org-agenda-todo arg)))
 
-;; arch-tag: 77f7565d-7c4b-44af-a2df-9f6f7070cff1
+(provide 'org-agenda)
 
 ;;; org-agenda.el ends here