]> code.delx.au - gnu-emacs/blobdiff - lisp/org/org-agenda.el
Simplify now that float-time etc. are built-in
[gnu-emacs] / lisp / org / org-agenda.el
index 116909da9fd0b7f86c539b5424d9d56aa2d388fd..fd5253ab1b7f8fc08eda3bf721cc973bd95b94e6 100644 (file)
@@ -1,6 +1,6 @@
 ;;; org-agenda.el --- Dynamic task and appointment lists for Org
 
-;; Copyright (C) 2004-2014 Free Software Foundation, Inc.
+;; Copyright (C) 2004-2016 Free Software Foundation, Inc.
 
 ;; Author: Carsten Dominik <carsten at orgmode dot org>
 ;; Keywords: outlines, hypermedia, calendar, wp
@@ -390,32 +390,36 @@ the daily/weekly agenda, see `org-agenda-skip-function'.")
                           (repeat :inline t :tag "Conditions for skipping"
                                   (choice
                                    :tag "Condition type"
-                                   (list :tag "Regexp matches" :inline t (const :format "" regexp) (regexp))
-                                   (list :tag "Regexp does not match" :inline t (const :format "" notregexp) (regexp))
+                                   (list :tag "Regexp matches" :inline t
+                                         (const :format "" 'regexp)
+                                         (regexp))
+                                   (list :tag "Regexp does not match" :inline t
+                                         (const :format "" 'notregexp)
+                                         (regexp))
                                    (list :tag "TODO state is" :inline t
-                                         (const todo)
+                                         (const 'todo)
                                          (choice
-                                          (const :tag "any not-done state" todo)
-                                          (const :tag "any done state" done)
-                                          (const :tag "any state" any)
+                                          (const :tag "Any not-done state" 'todo)
+                                          (const :tag "Any done state" 'done)
+                                          (const :tag "Any state" 'any)
                                           (list :tag "Keyword list"
                                                 (const :format "" quote)
                                                 (repeat (string :tag "Keyword")))))
                                    (list :tag "TODO state is not" :inline t
-                                         (const nottodo)
+                                         (const 'nottodo)
                                          (choice
-                                          (const :tag "any not-done state" todo)
-                                          (const :tag "any done state" done)
-                                          (const :tag "any state" any)
+                                          (const :tag "Any not-done state" 'todo)
+                                          (const :tag "Any done state" 'done)
+                                          (const :tag "Any state" 'any)
                                           (list :tag "Keyword list"
                                                 (const :format "" quote)
                                                 (repeat (string :tag "Keyword")))))
-                                   (const :tag "scheduled" scheduled)
-                                   (const :tag "not scheduled" notscheduled)
-                                   (const :tag "deadline" deadline)
-                                   (const :tag "no deadline" notdeadline)
-                                   (const :tag "timestamp" timestamp)
-                                   (const :tag "no timestamp" nottimestamp))))))
+                                   (const :tag "scheduled" 'scheduled)
+                                   (const :tag "not scheduled" 'notscheduled)
+                                   (const :tag "deadline" 'deadline)
+                                   (const :tag "no deadline" 'notdeadline)
+                                   (const :tag "timestamp" 'timestamp)
+                                   (const :tag "no timestamp" 'nottimestamp))))))
                   (list :tag "Non-standard skipping condition"
                         :value (org-agenda-skip-function)
                         (const org-agenda-skip-function)
@@ -429,7 +433,7 @@ This will be spliced into the custom type of
 
 
 (defcustom org-agenda-custom-commands
-  '(("n" "Agenda and all TODO's" ((agenda "") (alltodo ""))))
+  '(("n" "Agenda and all TODOs" ((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:
@@ -493,7 +497,7 @@ are prefix commands.  For the dispatcher to display useful information, you
 should provide a description for the prefix, like
 
  (setq org-agenda-custom-commands
-   '((\"h\" . \"HOME + Name tag searches\") ; describe prefix \"h\"
+   \\='((\"h\" . \"HOME + Name tag searches\") ; describe prefix \"h\"
      (\"hl\" tags \"+HOME+Lisa\")
      (\"hp\" tags \"+HOME+Peter\")
      (\"hk\" tags \"+HOME+Kim\")))"
@@ -649,8 +653,8 @@ of custom agenda commands."
   :tag "Org Agenda Match View"
   :group 'org-agenda)
 (defgroup org-agenda-search-view nil
-  "Options concerning the general tags/property/todo match agenda view."
-  :tag "Org Agenda Match View"
+  "Options concerning the search agenda view."
+  :tag "Org Agenda Search View"
   :group 'org-agenda)
 
 (defvar org-agenda-archives-mode nil
@@ -764,7 +768,7 @@ to make his option also apply to the tags-todo list."
          (integer :tag "Ignore if N or more days in past(-) or future(+).")))
 
 (defcustom org-agenda-todo-ignore-deadlines nil
-  "Non-nil means ignore some deadlined TODO items when making TODO list.
+  "Non-nil means ignore some deadline TODO items when making TODO list.
 There are different motivations for using different values, please think
 carefully when configuring this variable.
 
@@ -1207,7 +1211,7 @@ For example, 9:30am would become 09:30 rather than  9:30."
   :type 'boolean)
 
 (defun org-agenda-time-of-day-to-ampm (time)
-  "Convert TIME of a string like '13:45' to an AM/PM style time string."
+  "Convert TIME of a string like `13:45' to an AM/PM style time string."
   (let* ((hour-number (string-to-number (substring time 0 -3)))
          (minute (substring time -2))
          (ampm "am"))
@@ -1468,6 +1472,7 @@ symbols specifying conditions when the grid should be displayed:
  weekly        if the agenda shows an entire week
  today         show grid on current date, independent of daily/weekly display
  require-timed show grid only if at least one item has a time specification
+ remove-match  skip grid times already present in an entry
 
 The second item is a string which will be placed behind the grid time.
 
@@ -1927,7 +1932,7 @@ list as second element:
 For example, to display a 16px horizontal space for Emacs
 category, you can use:
 
-  (\"Emacs\" '(space . (:width (16))))"
+  (\"Emacs\" \\='(space . (:width (16))))"
   :group 'org-agenda-line-format
   :version "24.1"
   :type '(alist :key-type (string :tag "Regexp matching category")
@@ -1970,7 +1975,7 @@ estimate."
   :type 'boolean)
 
 (defcustom org-agenda-auto-exclude-function nil
-  "A function called with a tag to decide if it is filtered on '/ RET'.
+  "A function called with a tag to decide if it is filtered on `/ RET'.
 The sole argument to the function, which is called once for each
 possible tag, is a string giving the name of the tag.  The
 function should return either nil if the tag should be included
@@ -1985,8 +1990,8 @@ the lower-case version of all tags."
   "Alist of characters and custom functions for bulk actions.
 For example, this value makes those two functions available:
 
-  '((?R set-category)
-    (?C bulk-cut))
+  ((?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.
@@ -2092,11 +2097,9 @@ When nil, `q' will kill the single agenda buffer."
     org-agenda-info
     org-agenda-pre-window-conf
     org-agenda-columns-active
-    org-agenda-tag-filter-overlays
     org-agenda-tag-filter
-    org-agenda-cat-filter-overlays
     org-agenda-category-filter
-    org-agenda-re-filter-overlays
+    org-agenda-top-headline-filter
     org-agenda-regexp-filter
     org-agenda-markers
     org-agenda-last-search-view-search-was-boolean
@@ -2144,6 +2147,7 @@ The following commands are available:
   ;; Keep global-font-lock-mode from turning on font-lock-mode
   (org-set-local 'font-lock-global-modes (list 'not major-mode))
   (setq mode-name "Org-Agenda")
+  (setq indent-tabs-mode nil)
   (use-local-map org-agenda-mode-map)
   (easy-menu-add org-agenda-menu)
   (if org-startup-truncated (setq truncate-lines t))
@@ -2157,10 +2161,11 @@ The following commands are available:
                nil t)
   (unless org-agenda-keep-modes
     (setq org-agenda-follow-mode org-agenda-start-with-follow-mode
-         org-agenda-entry-text-mode org-agenda-start-with-entry-text-mode
-         org-agenda-clockreport-mode org-agenda-start-with-clockreport-mode
-         org-agenda-show-log org-agenda-start-with-log-mode))
-
+         org-agenda-entry-text-mode org-agenda-start-with-entry-text-mode))
+  (setq org-agenda-show-log org-agenda-start-with-log-mode)
+  (setq org-agenda-clockreport-mode org-agenda-start-with-clockreport-mode)
+  (add-to-invisibility-spec '(org-filtered))
+  (add-to-invisibility-spec '(org-link))
   (easy-menu-change
    '("Agenda") "Agenda Files"
    (append
@@ -2533,7 +2538,7 @@ For example, if you have a custom agenda command \"p\" and you
 want this command to be accessible only from plain text files,
 use this:
 
-   '((\"p\" ((in-file . \"\\.txt\"))))
+   \\='((\"p\" ((in-file . \"\\.txt\"))))
 
 Here are the available contexts definitions:
 
@@ -2551,7 +2556,7 @@ accessible if there is at least one valid check.
 You can also bind a key to another agenda custom command
 depending on contextual rules.
 
-    '((\"p\" \"q\" ((in-file . \"\\.txt\"))))
+    \\='((\"p\" \"q\" ((in-file . \"\\.txt\"))))
 
 Here it means: in .txt files, use \"p\" as the key for the
 agenda command otherwise associated with \"q\".  (The command
@@ -2603,7 +2608,7 @@ type."
   :package-version '(Org . "8.0")
   :group 'org-agenda-custom-commands
   :type '(choice (symbol :tag "No limit" nil)
-                (integer :tag "Max number of entries")
+                (integer :tag "Max number of TODOs")
                 (repeat
                  (cons (choice :tag "Agenda type"
                                (const agenda)
@@ -2611,7 +2616,7 @@ type."
                                (const tags)
                                (const search)
                                (const timeline))
-                       (integer :tag "Max number of entries")))))
+                       (integer :tag "Max number of TODOs")))))
 
 (defcustom org-agenda-max-tags nil
   "Maximum number of tagged entries to display in an agenda.
@@ -2622,7 +2627,7 @@ type."
   :package-version '(Org . "8.0")
   :group 'org-agenda-custom-commands
   :type '(choice (symbol :tag "No limit" nil)
-                (integer :tag "Max number of entries")
+                (integer :tag "Max number of tagged entries")
                 (repeat
                  (cons (choice :tag "Agenda type"
                                (const agenda)
@@ -2630,7 +2635,7 @@ type."
                                (const tags)
                                (const search)
                                (const timeline))
-                       (integer :tag "Max number of entries")))))
+                       (integer :tag "Max number of tagged entries")))))
 
 (defcustom org-agenda-max-effort nil
   "Maximum cumulated effort duration for the agenda.
@@ -2641,7 +2646,7 @@ to limit entries to in this type."
   :package-version '(Org . "8.0")
   :group 'org-agenda-custom-commands
   :type '(choice (symbol :tag "No limit" nil)
-                (integer :tag "Max number of entries")
+                (integer :tag "Max number of minutes")
                 (repeat
                  (cons (choice :tag "Agenda type"
                                (const agenda)
@@ -2649,7 +2654,7 @@ to limit entries to in this type."
                                (const tags)
                                (const search)
                                (const timeline))
-                       (integer :tag "Max number of entries")))))
+                       (integer :tag "Max number of minutes")))))
 
 (defvar org-keys nil)
 (defvar org-match nil)
@@ -3323,19 +3328,12 @@ If AGENDA-BUFFER-NAME, use this as the buffer name for the agenda to write."
   (org-let (if nosettings nil org-agenda-exporter-settings)
     '(save-excursion
        (save-window-excursion
-        (org-agenda-mark-filtered-text)
         (let ((bs (copy-sequence (buffer-string))) beg content)
-          (org-agenda-unmark-filtered-text)
           (with-temp-buffer
             (rename-buffer org-agenda-write-buffer-name t)
             (set-buffer-modified-p nil)
             (insert bs)
             (org-agenda-remove-marked-text 'org-filtered)
-            (while (setq beg (text-property-any (point-min) (point-max)
-                                                'org-filtered t))
-              (delete-region
-               beg (or (next-single-property-change beg 'org-filtered)
-                       (point-max))))
             (run-hooks 'org-agenda-before-write-hook)
             (cond
              ((org-bound-and-true-p org-mobile-creating-agendas)
@@ -3355,7 +3353,7 @@ If AGENDA-BUFFER-NAME, use this as the buffer name for the agenda to write."
                           content)))
                 (find-file file)
                 (erase-buffer)
-                (mapcar (lambda (s) (org-paste-subtree 1 s)) (reverse content))
+                (dolist (s content) (org-paste-subtree 1 s))
                 (write-file file)
                 (kill-buffer (current-buffer))
                 (message "Org file written to %s" file)))
@@ -3401,28 +3399,6 @@ If AGENDA-BUFFER-NAME, use this as the buffer name for the agenda to write."
                    org-agenda-buffer-name)))
   (when open (org-open-file file)))
 
-(defvar org-agenda-tag-filter-overlays nil)
-(defvar org-agenda-cat-filter-overlays nil)
-(defvar org-agenda-re-filter-overlays nil)
-
-(defun org-agenda-mark-filtered-text ()
-  "Mark all text hidden by filtering with a text property."
-  (let ((inhibit-read-only t))
-    (mapc
-     (lambda (o)
-       (when (equal (overlay-buffer o) (current-buffer))
-        (put-text-property
-         (overlay-start o) (overlay-end o)
-         'org-filtered t)))
-     (append org-agenda-tag-filter-overlays
-            org-agenda-cat-filter-overlays
-            org-agenda-re-filter-overlays))))
-
-(defun org-agenda-unmark-filtered-text ()
-  "Remove the filtering text property."
-  (let ((inhibit-read-only t))
-    (remove-text-properties (point-min) (point-max) '(org-filtered t))))
-
 (defun org-agenda-remove-marked-text (property &optional value)
   "Delete all text marked with VALUE of PROPERTY.
 VALUE defaults to t."
@@ -3431,7 +3407,7 @@ VALUE defaults to t."
     (while (setq beg (text-property-any (point-min) (point-max)
                                        property value))
       (delete-region
-       beg (or (next-single-property-change beg 'org-filtered)
+       beg (or (next-single-property-change beg property)
               (point-max))))))
 
 (defun org-agenda-add-entry-text ()
@@ -3556,7 +3532,6 @@ removed from the entry content.  Currently only `planning' is allowed here."
 (defvar org-agenda-category-filter nil)
 (defvar org-agenda-regexp-filter nil)
 (defvar org-agenda-top-headline-filter nil)
-(defvar org-agenda-tag-filter-while-redo nil)
 (defvar org-agenda-tag-filter-preset nil
   "A preset of the tags filter used for secondary agenda filtering.
 This must be a list of strings, each string must be a single tag preceded
@@ -3579,7 +3554,7 @@ the global options and expect it to be applied to the entire view.")
 
 (defvar org-agenda-regexp-filter-preset nil
   "A preset of the regexp filter used for secondary agenda filtering.
-This must be a list of strings, each string must be a single category
+This must be a list of strings, each string must be a single regexp
 preceded by \"+\" or \"-\".
 This variable should not be set directly, but agenda custom commands can
 bind it in the options section.  The preset filter is a global property of
@@ -3608,10 +3583,12 @@ generating a new one."
       ;; does not have org variables local
       org-agenda-this-buffer-is-sticky))))
 
-(defun org-agenda-prepare-window (abuf)
-  "Setup agenda buffer in the window."
-  (let* ((awin (get-buffer-window abuf))
-        wconf)
+(defun org-agenda-prepare-window (abuf filter-alist)
+  "Setup agenda buffer in the window.
+ABUF is the buffer for the agenda window.
+FILTER-ALIST is an alist of filters we need to apply when
+`org-agenda-persistent-filter' is non-nil."
+  (let* ((awin (get-buffer-window abuf)) wconf)
     (cond
      ((equal (current-buffer) abuf) nil)
      (awin (select-window awin))
@@ -3625,68 +3602,76 @@ generating a new one."
      ((equal org-agenda-window-setup 'reorganize-frame)
       (delete-other-windows)
       (org-switch-to-buffer-other-window abuf)))
-    ;; additional test in case agenda is invoked from within agenda
-    ;; buffer via elisp link
+    (setq org-agenda-tag-filter (cdr (assoc 'tag filter-alist)))
+    (setq org-agenda-category-filter (cdr (assoc 'cat filter-alist)))
+    (setq org-agenda-regexp-filter (cdr (assoc 're filter-alist)))
+    ;; Additional test in case agenda is invoked from within agenda
+    ;; buffer via elisp link.
     (unless (equal (current-buffer) abuf)
       (org-pop-to-buffer-same-window abuf))
     (setq org-agenda-pre-window-conf
          (or org-agenda-pre-window-conf wconf))))
 
 (defun org-agenda-prepare (&optional name)
-  (if (org-agenda-use-sticky-p)
-      (progn
-       ;; Popup existing buffer
-       (org-agenda-prepare-window (get-buffer org-agenda-buffer-name))
-       (message "Sticky Agenda buffer, use `r' to refresh")
-       (or org-agenda-multi (org-agenda-fit-window-to-buffer))
-       (throw 'exit "Sticky Agenda buffer, use `r' to refresh"))
-    (setq org-todo-keywords-for-agenda nil)
-    (setq org-drawers-for-agenda nil)
-    (unless org-agenda-persistent-filter
-      (setq org-agenda-tag-filter nil
-           org-agenda-category-filter nil
-           org-agenda-regexp-filter nil))
-    (put 'org-agenda-tag-filter :preset-filter
-        org-agenda-tag-filter-preset)
-    (put 'org-agenda-category-filter :preset-filter
-        org-agenda-category-filter-preset)
-    (put 'org-agenda-regexp-filter :preset-filter
-        org-agenda-regexp-filter-preset)
-    (if org-agenda-multi
+  (let ((filter-alist (if org-agenda-persistent-filter
+                         (list `(tag . ,org-agenda-tag-filter)
+                               `(re . ,org-agenda-regexp-filter)
+                               `(car . ,org-agenda-category-filter)))))
+    (if (org-agenda-use-sticky-p)
        (progn
-         (setq buffer-read-only nil)
-         (goto-char (point-max))
-         (unless (or (bobp) org-agenda-compact-blocks
-                     (not org-agenda-block-separator))
-           (insert "\n"
-                   (if (stringp org-agenda-block-separator)
-                       org-agenda-block-separator
-                     (make-string (window-width) org-agenda-block-separator))
-                   "\n"))
-         (narrow-to-region (point) (point-max)))
-      (setq org-done-keywords-for-agenda nil)
-
-      ;; Setting any org variables that are in org-agenda-local-vars
-      ;; list need to be done after the prepare call
-      (org-agenda-prepare-window (get-buffer-create org-agenda-buffer-name))
-      (setq buffer-read-only nil)
-      (org-agenda-reset-markers)
-      (let ((inhibit-read-only t)) (erase-buffer))
-      (org-agenda-mode)
-      (setq org-agenda-buffer (current-buffer))
-      (setq org-agenda-contributing-files nil)
-      (setq org-agenda-columns-active nil)
-      (org-agenda-prepare-buffers (org-agenda-files nil 'ifmode))
-      (setq org-todo-keywords-for-agenda
-           (org-uniquify org-todo-keywords-for-agenda))
-      (setq org-done-keywords-for-agenda
-           (org-uniquify org-done-keywords-for-agenda))
-      (setq org-drawers-for-agenda (org-uniquify org-drawers-for-agenda))
-      (setq org-agenda-last-prefix-arg current-prefix-arg)
-      (setq org-agenda-this-buffer-name org-agenda-buffer-name)
-      (and name (not org-agenda-name)
-          (org-set-local 'org-agenda-name name)))
-    (setq buffer-read-only nil)))
+         (put 'org-agenda-tag-filter :preset-filter nil)
+         (put 'org-agenda-category-filter :preset-filter nil)
+         (put 'org-agenda-regexp-filter :preset-filter nil)
+         ;; Popup existing buffer
+         (org-agenda-prepare-window (get-buffer org-agenda-buffer-name)
+                                    filter-alist)
+         (message "Sticky Agenda buffer, use `r' to refresh")
+         (or org-agenda-multi (org-agenda-fit-window-to-buffer))
+         (throw 'exit "Sticky Agenda buffer, use `r' to refresh"))
+      (setq org-todo-keywords-for-agenda nil)
+      (setq org-drawers-for-agenda nil)
+      (put 'org-agenda-tag-filter :preset-filter
+          org-agenda-tag-filter-preset)
+      (put 'org-agenda-category-filter :preset-filter
+          org-agenda-category-filter-preset)
+      (put 'org-agenda-regexp-filter :preset-filter
+          org-agenda-regexp-filter-preset)
+      (if org-agenda-multi
+         (progn
+           (setq buffer-read-only nil)
+           (goto-char (point-max))
+           (unless (or (bobp) org-agenda-compact-blocks
+                       (not org-agenda-block-separator))
+             (insert "\n"
+                     (if (stringp org-agenda-block-separator)
+                         org-agenda-block-separator
+                       (make-string (window-width) org-agenda-block-separator))
+                     "\n"))
+           (narrow-to-region (point) (point-max)))
+       (setq org-done-keywords-for-agenda nil)
+
+       ;; Setting any org variables that are in org-agenda-local-vars
+       ;; list need to be done after the prepare call
+       (org-agenda-prepare-window
+        (get-buffer-create org-agenda-buffer-name) filter-alist)
+       (setq buffer-read-only nil)
+       (org-agenda-reset-markers)
+       (let ((inhibit-read-only t)) (erase-buffer))
+       (org-agenda-mode)
+       (setq org-agenda-buffer (current-buffer))
+       (setq org-agenda-contributing-files nil)
+       (setq org-agenda-columns-active nil)
+       (org-agenda-prepare-buffers (org-agenda-files nil 'ifmode))
+       (setq org-todo-keywords-for-agenda
+             (org-uniquify org-todo-keywords-for-agenda))
+       (setq org-done-keywords-for-agenda
+             (org-uniquify org-done-keywords-for-agenda))
+       (setq org-drawers-for-agenda (org-uniquify org-drawers-for-agenda))
+       (setq org-agenda-last-prefix-arg current-prefix-arg)
+       (setq org-agenda-this-buffer-name org-agenda-buffer-name)
+       (and name (not org-agenda-name)
+            (org-set-local 'org-agenda-name name)))
+      (setq buffer-read-only nil))))
 
 (defvar org-agenda-overriding-columns-format)  ; From org-colview.el
 (defun org-agenda-finalize ()
@@ -3718,12 +3703,7 @@ generating a new one."
          (org-agenda-fontify-priorities))
        (when (and org-agenda-dim-blocked-tasks org-blocker-hook)
          (org-agenda-dim-blocked-tasks))
-       ;; We need to widen when `org-agenda-finalize' is called from
-       ;; `org-agenda-change-all-lines' (e.g. in `org-agenda-clock-in')
-       (when org-clock-current-task
-         (save-restriction
-           (widen)
-           (org-agenda-mark-clocking-task)))
+       (org-agenda-mark-clocking-task)
        (when org-agenda-entry-text-mode
          (org-agenda-entry-text-hide)
          (org-agenda-entry-text-show))
@@ -3743,37 +3723,53 @@ generating a new one."
            (save-excursion
              (goto-char (point-min))
              (while (equal (forward-line) 0)
-               (when (setq mrk (or (get-text-property (point) 'org-hd-marker)
-                                   (get-text-property (point) 'org-hd-marker)))
+               (when (setq mrk (get-text-property (point) 'org-hd-marker))
                  (put-text-property (point-at-bol) (point-at-eol)
                                     'tags (org-with-point-at mrk
                                             (delete-dups
                                              (mapcar 'downcase (org-get-tags-at))))))))))
        (run-hooks 'org-agenda-finalize-hook)
-       (when (or org-agenda-tag-filter (get 'org-agenda-tag-filter :preset-filter))
+       (when org-agenda-top-headline-filter
+         (org-agenda-filter-top-headline-apply
+          org-agenda-top-headline-filter))
+       (when org-agenda-tag-filter
          (org-agenda-filter-apply org-agenda-tag-filter 'tag))
-       (when (or org-agenda-category-filter (get 'org-agenda-category-filter :preset-filter))
+       (when (get 'org-agenda-tag-filter :preset-filter)
+         (org-agenda-filter-apply
+          (get 'org-agenda-tag-filter :preset-filter) 'tag))
+       (when org-agenda-category-filter
          (org-agenda-filter-apply org-agenda-category-filter 'category))
-       (when (or org-agenda-regexp-filter (get 'org-agenda-regexp-filter :preset-filter))
+       (when (get 'org-agenda-category-filter :preset-filter)
+         (org-agenda-filter-apply
+          (get 'org-agenda-category-filter :preset-filter) 'category))
+       (when org-agenda-regexp-filter
          (org-agenda-filter-apply org-agenda-regexp-filter 'regexp))
+       (when (get 'org-agenda-regexp-filter :preset-filter)
+         (org-agenda-filter-apply
+          (get 'org-agenda-regexp-filter :preset-filter) 'regexp))
        (org-add-hook 'kill-buffer-hook 'org-agenda-reset-markers 'append 'local)))))
 
 (defun org-agenda-mark-clocking-task ()
   "Mark the current clock entry in the agenda if it is present."
-  (org-agenda-unmark-clocking-task)
-  (when (marker-buffer org-clock-hd-marker)
-    (save-excursion
-      (goto-char (point-min))
-      (let (s ov)
-       (while (setq s (next-single-property-change (point) 'org-hd-marker))
-         (goto-char s)
-         (when (equal (org-get-at-bol 'org-hd-marker)
-                      org-clock-hd-marker)
-           (setq ov (make-overlay (point-at-bol) (1+ (point-at-eol))))
-           (overlay-put ov 'type 'org-agenda-clocking)
-           (overlay-put ov 'face 'org-agenda-clocking)
-           (overlay-put ov 'help-echo
-                        "The clock is running in this item")))))))
+  ;; We need to widen when `org-agenda-finalize' is called from
+  ;; `org-agenda-change-all-lines' (e.g. in `org-agenda-clock-in')
+  (when org-clock-current-task
+    (save-restriction
+      (widen)
+      (org-agenda-unmark-clocking-task)
+      (when (marker-buffer org-clock-hd-marker)
+       (save-excursion
+         (goto-char (point-min))
+         (let (s ov)
+           (while (setq s (next-single-property-change (point) 'org-hd-marker))
+             (goto-char s)
+             (when (equal (org-get-at-bol 'org-hd-marker)
+                          org-clock-hd-marker)
+               (setq ov (make-overlay (point-at-bol) (1+ (point-at-eol))))
+               (overlay-put ov 'type 'org-agenda-clocking)
+               (overlay-put ov 'face 'org-agenda-clocking)
+               (overlay-put ov 'help-echo
+                            "The clock is running in this item")))))))))
 
 (defun org-agenda-unmark-clocking-task ()
   "Unmark the current clocking task."
@@ -3819,7 +3815,7 @@ generating a new one."
 (defvar org-depend-tag-blocked)
 
 (defun org-agenda-dim-blocked-tasks (&optional invisible)
-  "Dim currently blocked TODO's in the agenda display.
+  "Dim currently blocked TODOs in the agenda display.
 When INVISIBLE is non-nil, hide currently blocked TODO instead of
 dimming them."
   (interactive "P")
@@ -3851,11 +3847,12 @@ dimming them."
                  e (point-at-eol)
                  ov (make-overlay b e))
            (if invis1
-               (overlay-put ov 'invisible t)
+               (progn (overlay-put ov 'invisible t)
+                      (overlay-put ov 'intangible t))
              (overlay-put ov 'face 'org-agenda-dimmed-todo-face))
            (overlay-put ov 'org-type 'org-blocked-todo))))))
-    (when (org-called-interactively-p 'interactive)
-      (message "Dim or hide blocked tasks...done")))
+  (when (org-called-interactively-p 'interactive)
+    (message "Dim or hide blocked tasks...done")))
 
 (defvar org-agenda-skip-function nil
   "Function to be called at each match during agenda construction.
@@ -3906,7 +3903,7 @@ functions do."
 
 (defvar org-agenda-markers nil
   "List of all currently active markers created by `org-agenda'.")
-(defvar org-agenda-last-marker-time (org-float-time)
+(defvar org-agenda-last-marker-time (float-time)
   "Creation time of the last agenda marker.")
 
 (defun org-agenda-new-marker (&optional pos)
@@ -3914,7 +3911,7 @@ functions do."
 Org-mode keeps a list of these markers and resets them when they are
 no longer in use."
   (let ((m (copy-marker (or pos (point)))))
-    (setq org-agenda-last-marker-time (org-float-time))
+    (setq org-agenda-last-marker-time (float-time))
     (if org-agenda-buffer
        (with-current-buffer org-agenda-buffer
          (push m org-agenda-markers))
@@ -4315,14 +4312,6 @@ items if they have an hour specification like [h]h:mm."
          (setq p (plist-put p :tstart clocktable-start))
          (setq p (plist-put p :tend clocktable-end))
          (setq p (plist-put p :scope 'agenda))
-         (when (and (eq org-agenda-clockreport-mode 'with-filter)
-                    (setq filter (or org-agenda-tag-filter-while-redo
-                                     (get 'org-agenda-tag-filter :preset-filter))))
-           (setq p (plist-put p :tags (mapconcat (lambda (x)
-                                                   (if (string-match "[<>=]" x)
-                                                       ""
-                                                     x))
-                                                 filter ""))))
          (setq tbl (apply 'org-clock-get-clocktable p))
          (insert tbl)))
       (goto-char (point-min))
@@ -4614,7 +4603,8 @@ in `org-agenda-text-search-extra-files'."
                                             (goto-char (1- end))
                                             (throw :skip t)))
                              (if todo-only
-                                 (cons (concat "^\*+[ \t]+" org-not-done-regexp)
+                                 (cons (concat "^\\*+[ \t]+"
+                                                org-not-done-regexp)
                                        regexps+)
                                regexps+))
                        (goto-char beg)
@@ -4658,7 +4648,8 @@ in `org-agenda-text-search-extra-files'."
        (add-text-properties pos (1- (point)) (list 'face 'org-warning))
        (setq pos (point))
        (unless org-agenda-multi
-         (insert "Press `[', `]' to add/sub word, `{', `}' to add/sub regexp, `C-u r' to edit\n")
+         (insert (substitute-command-keys
+                  "Press `[', `]' to add/sub word, `{', `}' to add/sub regexp, `C-u r' to edit\n"))
          (add-text-properties pos (1- (point))
                               (list 'face 'org-agenda-structure))))
       (org-agenda-mark-header-line (point-min))
@@ -4752,7 +4743,7 @@ for a keyword.  A numeric prefix directly selects the Nth keyword in
                 org-select-this-todo-keyword))
        (setq pos (point))
        (unless org-agenda-multi
-         (insert "Available with `N r': (0)[ALL]")
+         (insert (substitute-command-keys "Available with `N r': (0)[ALL]"))
          (let ((n 0) s)
            (mapc (lambda (x)
                    (setq s (format "(%d)%s" (setq n (1+ n)) x))
@@ -4847,7 +4838,8 @@ The prefix arg TODO-ONLY limits the search to TODO entries."
        (add-text-properties pos (1- (point)) (list 'face 'org-warning))
        (setq pos (point))
        (unless org-agenda-multi
-         (insert "Press `C-u r' to search again with new search string\n"))
+         (insert (substitute-command-keys
+                  "Press `C-u r' to search again with new search string\n")))
        (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure)))
       (org-agenda-mark-header-line (point-min))
       (when rtnall
@@ -4917,7 +4909,7 @@ See `org-agenda-skip-if' for details."
   (org-agenda-skip-if nil conditions))
 
 (defun org-agenda-skip-subtree-if (&rest conditions)
-  "Skip entry if any of CONDITIONS is true.
+  "Skip subtree if any of CONDITIONS is true.
 See `org-agenda-skip-if' for details."
   (org-agenda-skip-if t conditions))
 
@@ -4946,13 +4938,13 @@ the `regexp' or `notregexp' element.
 `todo' and `nottodo' accept as an argument a list of todo
 keywords, which may include \"*\" to match any todo keyword.
 
-    (org-agenda-skip-entry-if 'todo '(\"TODO\" \"WAITING\"))
+    (org-agenda-skip-entry-if \\='todo \\='(\"TODO\" \"WAITING\"))
 
 would skip all entries with \"TODO\" or \"WAITING\" keywords.
 
 Instead of a list, a keyword class may be given.  For example:
 
-    (org-agenda-skip-entry-if 'nottodo 'done)
+    (org-agenda-skip-entry-if \\='nottodo \\='done)
 
 would skip entries that haven't been marked with any of \"DONE\"
 keywords.  Possible classes are: `todo', `done', `any'.
@@ -5086,6 +5078,7 @@ of what a project is and how to check if it stuck, customize the variable
              (mapconcat 'identity re-list "\\|")
            (error "No information how to identify unstuck projects")))
     (org-tags-view nil matcher)
+    (setq org-agenda-buffer-name (buffer-name))
     (with-current-buffer org-agenda-buffer-name
       (setq org-agenda-redo-command
            `(org-agenda-list-stuck-projects ,current-prefix-arg)))))
@@ -5099,8 +5092,7 @@ of what a project is and how to check if it stuck, customize the variable
   "Get the (Emacs Calendar) diary entries for DATE."
   (require 'diary-lib)
   (let* ((diary-fancy-buffer "*temporary-fancy-diary-buffer*")
-        (diary-display-hook '(fancy-diary-display))
-        (diary-display-function 'fancy-diary-display)
+        (diary-display-function 'diary-fancy-display)
         (pop-up-frames nil)
         (diary-list-entries-hook
          (cons 'org-diary-default-entry diary-list-entries-hook))
@@ -5239,7 +5231,7 @@ So the example above may also be written as
 The function expects the lisp variables `entry' and `date' to be provided
 by the caller, because this is how the calendar works.  Don't use this
 function from a program - use `org-agenda-get-day-entries' instead."
-  (when (> (- (org-float-time)
+  (when (> (- (float-time)
              org-agenda-last-marker-time)
           5)
     ;; I am not sure if this works with sticky agendas, because the marker
@@ -5251,7 +5243,7 @@ function from a program - use `org-agenda-get-day-entries' instead."
   (let* ((files (if (and entry (stringp entry) (string-match "\\S-" entry))
                    (list entry)
                  (org-agenda-files t)))
-        (time (org-float-time))
+        (time (float-time))
         file rtn results)
     (when (or (not org-diary-last-run-time)
              (> (- time
@@ -5453,7 +5445,7 @@ This function is invoked if `org-agenda-todo-ignore-deadlines',
 
 ;;;###autoload
 (defun org-agenda-check-for-timestamp-as-reason-to-ignore-todo-item
-  (&optional end)
+    (&optional end)
   "Do we have a reason to ignore this TODO entry because it has a time stamp?"
   (when (or org-agenda-todo-ignore-with-date
            org-agenda-todo-ignore-scheduled
@@ -5690,10 +5682,10 @@ This function is invoked if `org-agenda-todo-ignore-deadlines',
              (setq txt "SEXP entry returned empty string"))
            (setq txt (org-agenda-format-item extra txt level category tags 'time))
            (org-add-props txt props 'org-marker marker
-             'org-category category 'date date 'todo-state todo-state
-             'org-category-position category-pos 'tags tags
-             'level level
-             'type "sexp" 'warntime warntime)
+                          'org-category category 'date date 'todo-state todo-state
+                          'org-category-position category-pos
+                          'level level
+                          'type "sexp" 'warntime warntime)
            (push txt ee)))))
     (nreverse ee)))
 
@@ -5723,7 +5715,7 @@ This function is invoked if `org-agenda-todo-ignore-deadlines',
    (let ((calendar-date-style 'european)       (european-calendar-style t))
      (diary-date day month year mark))))
 
-;; Define theorg-class' function
+;; 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.
 DAYNAME is a number between 0 (Sunday) and 6 (Saturday).
@@ -5920,9 +5912,9 @@ See also the user option `org-agenda-clock-consistency-checks'."
              (throw 'next t))
            (setq ts (match-string 1)
                  te (match-string 3)
-                 ts (org-float-time
+                 ts (float-time
                      (apply 'encode-time (org-parse-time-string ts)))
-                 te (org-float-time
+                 te (float-time
                      (apply 'encode-time (org-parse-time-string te)))
                  dt (- te ts))))
        (cond
@@ -6244,6 +6236,7 @@ an hour specification like [h]h:mm."
                    category-pos (get-text-property (point) 'org-category-position))
              (if (and (eq org-agenda-skip-scheduled-if-deadline-is-shown
                           'repeated-after-deadline)
+                      (org-get-deadline-time (point))
                       (<= 0 (- d2 (time-to-days (org-get-deadline-time (point))))))
                  (throw :skip nil))
              (if (not (re-search-backward "^\\*+[ \t]+" nil t))
@@ -6652,7 +6645,7 @@ The modified list may contain inherited tags, and tags matched by
 
 LIST is the list of agenda items formatted by `org-agenda-list'.
 NDAYS is the span of the current agenda view.
-TODAYP is `t' when the current agenda view is on today."
+TODAYP is t when the current agenda view is on today."
   (catch 'exit
     (cond ((not org-agenda-use-time-grid) (throw 'exit list))
          ((and todayp (member 'today (car org-agenda-time-grid))))
@@ -6768,8 +6761,10 @@ The optional STRING argument forces conversion into a 5 character wide string
 HH:MM."
   (save-match-data
     (when
-       (or (string-match "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)\\([AaPp][Mm]\\)?\\> *" s)
-           (string-match "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)?\\([AaPp][Mm]\\)\\> *" s))
+       (and
+        (or (string-match "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)\\([AaPp][Mm]\\)?\\> *" s)
+            (string-match "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)?\\([AaPp][Mm]\\)\\> *" s))
+        (not (eq (get-text-property 1 'face s) 'org-link)))
       (let* ((h (string-to-number (match-string 1 s)))
             (m (if (match-end 3) (string-to-number (match-string 3 s)) 0))
             (ampm (if (match-end 4) (downcase (match-string 4 s))))
@@ -6997,7 +6992,7 @@ The optional argument TYPE tells the agenda type."
     (cond ((< ta tb) -1)
          ((< tb ta) +1))))
 
-(defsubst org-cmp-ts (a b &optional type)
+(defsubst org-cmp-ts (a b type)
   "Compare the timestamps values of entries A and B.
 When TYPE is \"scheduled\", \"deadline\", \"timestamp\" or
 \"timestamp_ia\", compare within each of these type.  When TYPE
@@ -7005,9 +7000,11 @@ is the empty string, compare all timestamps without respect of
 their type."
   (let* ((def (if org-sort-agenda-notime-is-late most-positive-fixnum -1))
         (ta (or (and (string-match type (or (get-text-property 1 'type a) ""))
-                     (get-text-property 1 'ts-date a)) def))
+                     (get-text-property 1 'ts-date a))
+                def))
         (tb (or (and (string-match type (or (get-text-property 1 'type b) ""))
-                     (get-text-property 1 'ts-date b)) def)))
+                     (get-text-property 1 'ts-date b))
+                def)))
     (cond ((< ta tb) -1)
          ((< tb ta) +1))))
 
@@ -7033,7 +7030,7 @@ their type."
                               (org-cmp-ts a b "deadline")))
         (deadline-down   (if deadline-up (- deadline-up) nil))
         (tsia-up         (and (org-em 'tsia-up 'tsia-down ss)
-                              (org-cmp-ts a b "iatimestamp_ia")))
+                              (org-cmp-ts a b "timestamp_ia")))
         (tsia-down       (if tsia-up (- tsia-up) nil))
         (ts-up           (and (org-em 'ts-up 'ts-down ss)
                               (org-cmp-ts a b "timestamp")))
@@ -7088,8 +7085,8 @@ their type."
 ;;;###autoload
 (defun org-agenda-set-restriction-lock (&optional type)
   "Set restriction lock for agenda, to current subtree or file.
-Restriction will be the file if TYPE is `file', or if type is the
-universal prefix '(4), or if the cursor is before the first headline
+Restriction will be the file if TYPE is `file', or if TYPE is the
+universal prefix `(4)', or if the cursor is before the first headline
 in the file.  Otherwise, restriction will be to the current subtree."
   (interactive "P")
   (and (equal type '(4)) (setq type 'file))
@@ -7270,7 +7267,6 @@ in the agenda."
         (cat-preset (get 'org-agenda-category-filter :preset-filter))
         (re-filter org-agenda-regexp-filter)
         (re-preset (get 'org-agenda-regexp-filter :preset-filter))
-        (org-agenda-tag-filter-while-redo (or tag-filter tag-preset))
         (cols org-agenda-columns-active)
         (line (org-current-line))
         (window-line (- line (org-current-line (window-start))))
@@ -7303,9 +7299,12 @@ in the agenda."
     (put 'org-agenda-tag-filter :preset-filter tag-preset)
     (put 'org-agenda-category-filter :preset-filter cat-preset)
     (put 'org-agenda-regexp-filter :preset-filter re-preset)
-    (and (or tag-filter tag-preset) (org-agenda-filter-apply tag-filter 'tag))
-    (and (or cat-filter cat-preset) (org-agenda-filter-apply cat-filter 'category))
-    (and (or re-filter re-preset) (org-agenda-filter-apply re-filter 'regexp))
+    (let ((tag (or tag-filter tag-preset))
+         (cat (or cat-filter cat-preset))
+         (re  (or re-filter re-preset)))
+      (when tag (org-agenda-filter-apply tag 'tag))
+      (when cat (org-agenda-filter-apply cat 'category))
+      (when re  (org-agenda-filter-apply re 'regexp)))
     (and top-hl-filter (org-agenda-filter-top-headline-apply top-hl-filter))
     (and cols (org-called-interactively-p 'any) (org-agenda-columns))
     (org-goto-line line)
@@ -7331,7 +7330,7 @@ The category is that of the current line."
         (org-agenda-filter-apply
          (setq org-agenda-category-filter
               (list (concat "+" cat))) 'category))
-       ((error "No category at point"))))))
+       ((error "No category at point"))))))
 
 (defun org-find-top-headline (&optional pos)
   "Find the topmost parent headline and return it."
@@ -7352,10 +7351,10 @@ The top headline is that of the current line."
       (progn
         (setq org-agenda-filtered-by-top-headline nil
              org-agenda-top-headline-filter nil)
-        (org-agenda-filter-show-all-cat))
-    (let ((cat (org-find-top-headline (org-get-at-bol 'org-hd-marker))))
-      (if cat (org-agenda-filter-top-headline-apply cat strip)
-        (error "No top-level category at point")))))
+        (org-agenda-filter-show-all-top-filter))
+    (let ((toph (org-find-top-headline (org-get-at-bol 'org-hd-marker))))
+      (if toph (org-agenda-filter-top-headline-apply toph strip)
+        (error "No top-level headline at point")))))
 
 (defvar org-agenda-regexp-filter nil)
 (defun org-agenda-filter-by-regexp (strip)
@@ -7370,7 +7369,7 @@ With two prefix arguments, remove the regexp filters."
                         (read-from-minibuffer
                          (if (equal strip '(4))
                              "Filter out entries matching regexp: "
-                             "Narrow to entries matching regexp: ")))))
+                           "Narrow to entries matching regexp: ")))))
        (push flt org-agenda-regexp-filter)
        (org-agenda-filter-apply org-agenda-regexp-filter 'regexp))
     (org-agenda-filter-show-all-re)
@@ -7384,7 +7383,10 @@ With two prefix arguments, remove the regexp filters."
   (when org-agenda-category-filter
     (org-agenda-filter-show-all-cat))
   (when org-agenda-regexp-filter
-    (org-agenda-filter-show-all-re)))
+    (org-agenda-filter-show-all-re))
+  (when org-agenda-top-headline-filter
+    (org-agenda-filter-show-all-top-filter))
+  (org-agenda-finalize))
 
 (defun org-agenda-filter-by-tag (strip &optional char narrow)
   "Keep only those lines in the agenda buffer that have a specific tag.
@@ -7487,8 +7489,7 @@ to switch to narrowing."
       (org-agenda-filter-apply org-agenda-tag-filter 'tag)
       (setq maybe-refresh t))
      (t (error "Invalid tag selection character %c" char)))
-    (when (and maybe-refresh
-              (eq org-agenda-clockreport-mode 'with-filter))
+    (when maybe-refresh
       (org-agenda-redo))))
 
 (defun org-agenda-get-represented-tags ()
@@ -7609,13 +7610,12 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags."
   ;; Deactivate `org-agenda-entry-text-mode' when filtering
   (if org-agenda-entry-text-mode (org-agenda-entry-text-mode))
   (let (tags cat txt)
-    (setq org-agenda-filter-form
-         (org-agenda-filter-make-matcher filter type))
-    (if (and (eq type 'category)
-            (not (equal (substring (car filter) 0 1) "-")))
-       ;; Only set `org-agenda-filtered-by-category' to t
-       ;; when a unique category is used as the filter
-       (setq org-agenda-filtered-by-category t))
+    (setq org-agenda-filter-form (org-agenda-filter-make-matcher filter type))
+    ;; Only set `org-agenda-filtered-by-category' to t when a unique
+    ;; category is used as the filter:
+    (setq org-agenda-filtered-by-category
+         (and (eq type 'category)
+              (not (equal (substring (car filter) 0 1) "-"))))
     (org-agenda-set-mode-name)
     (save-excursion
       (goto-char (point-min))
@@ -7645,8 +7645,8 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags."
       (let* ((pos (org-get-at-bol 'org-hd-marker))
              (tophl (and pos (org-find-top-headline pos))))
         (if (and tophl (funcall (if negative 'identity 'not)
-                                 (string= hl tophl)))
-            (org-agenda-filter-hide-line 'category)))
+                               (string= hl tophl)))
+            (org-agenda-filter-hide-line 'top-headline)))
       (beginning-of-line 2)))
   (if (get-char-property (point) 'invisible)
       (org-agenda-previous-line))
@@ -7655,50 +7655,36 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags."
 
 (defun org-agenda-filter-hide-line (type)
   "Hide lines with TYPE in the agenda buffer."
-  (let (ov)
-    (setq ov (make-overlay (max (point-min) (1- (point-at-bol)))
-                          (point-at-eol)))
-    (overlay-put ov 'invisible t)
-    (overlay-put ov 'type type)
-    (cond ((eq type 'tag) (push ov org-agenda-tag-filter-overlays))
-         ((eq type 'category) (push ov org-agenda-cat-filter-overlays))
-         ((eq type 'regexp) (push ov org-agenda-re-filter-overlays)))))
-
-(defun org-agenda-fix-tags-filter-overlays-at (&optional pos)
-  (setq pos (or pos (point)))
+  (let* ((b (max (point-min) (1- (point-at-bol))))
+        (e (point-at-eol)))
+    (let ((inhibit-read-only t))
+      (add-text-properties
+       b e `(invisible org-filtered org-filter-type ,type)))))
+
+(defun org-agenda-remove-filter (type)
+  (interactive)
+  "Remove filter of type TYPE from the agenda buffer."
   (save-excursion
-    (dolist (ov (overlays-at pos))
-      (when (and (overlay-get ov 'invisible)
-                (eq (overlay-get ov 'type) 'tag))
+    (goto-char (point-min))
+    (let ((inhibit-read-only t) pos)
+      (while (setq pos (text-property-any (point) (point-max) 'org-filter-type type))
        (goto-char pos)
-       (if (< (overlay-start ov) (point-at-eol))
-           (move-overlay ov (point-at-eol)
-                         (overlay-end ov)))))))
+       (remove-text-properties
+        (point) (next-single-property-change (point) 'org-filter-type)
+        `(invisible org-filtered org-filter-type ,type))))
+    (set (intern (format "org-agenda-%s-filter" (intern-soft type))) nil)
+    (setq org-agenda-filter-form nil)
+    (org-agenda-set-mode-name)
+    (org-agenda-finalize)))
 
 (defun org-agenda-filter-show-all-tag nil
-  "Remove tag filter overlays from the agenda buffer."
-  (mapc 'delete-overlay org-agenda-tag-filter-overlays)
-  (setq org-agenda-tag-filter-overlays nil
-       org-agenda-tag-filter nil
-       org-agenda-filter-form nil)
-  (org-agenda-set-mode-name))
-
+  (org-agenda-remove-filter 'tag))
 (defun org-agenda-filter-show-all-re nil
-  "Remove regexp filter overlays from the agenda buffer."
-  (mapc 'delete-overlay org-agenda-re-filter-overlays)
-  (setq org-agenda-re-filter-overlays nil
-       org-agenda-regexp-filter nil
-       org-agenda-filter-form nil)
-  (org-agenda-set-mode-name))
-
+  (org-agenda-remove-filter 'regexp))
 (defun org-agenda-filter-show-all-cat nil
-  "Remove category filter overlays from the agenda buffer."
-  (mapc 'delete-overlay org-agenda-cat-filter-overlays)
-  (setq org-agenda-cat-filter-overlays nil
-       org-agenda-filtered-by-category nil
-       org-agenda-category-filter nil
-       org-agenda-filter-form nil)
-  (org-agenda-set-mode-name))
+  (org-agenda-remove-filter 'category))
+(defun org-agenda-filter-show-all-top-filter nil
+  (org-agenda-remove-filter 'top-headline))
 
 (defun org-agenda-manipulate-query-add ()
   "Manipulate the query by adding a search term with positive selection.
@@ -8092,15 +8078,12 @@ so that the date SD will be in that range."
               (format " (maximum number of lines is %d)"
                       (if (integerp arg) arg org-agenda-entry-text-maxlines))))))
 
-(defun org-agenda-clockreport-mode (&optional with-filter)
-  "Toggle clocktable mode in an agenda buffer.
-With prefix arg WITH-FILTER, make the clocktable respect the current
-agenda filter."
-  (interactive "P")
+(defun org-agenda-clockreport-mode ()
+  "Toggle clocktable mode in an agenda buffer."
+  (interactive)
   (org-agenda-check-type t 'agenda)
-  (if with-filter
-      (setq org-agenda-clockreport-mode 'with-filter)
-    (setq org-agenda-clockreport-mode (not org-agenda-clockreport-mode)))
+  (setq org-agenda-clockreport-mode (not org-agenda-clockreport-mode))
+  (setq org-agenda-start-with-clockreport-mode org-agenda-clockreport-mode)
   (org-agenda-set-mode-name)
   (org-agenda-redo)
   (message "Clocktable mode is %s"
@@ -8121,6 +8104,7 @@ With a double `C-u' prefix arg, show *only* log items, nothing else."
              nil 'clockcheck))
         (special '(closed clock state))
         (t (not org-agenda-show-log))))
+  (setq org-agenda-start-with-log-mode org-agenda-show-log)
   (org-agenda-set-mode-name)
   (org-agenda-redo)
   (message "Log mode is %s"
@@ -8238,10 +8222,7 @@ When called with a prefix argument, include all archive files as well."
                      " Archives"
                    (format " :%s:" org-archive-tag))
                "")
-             (if org-agenda-clockreport-mode
-                 (if (eq org-agenda-clockreport-mode 'with-filter)
-                     " Clock{}" " Clock")
-               "")))
+             (if org-agenda-clockreport-mode " Clock" "")))
   (force-mode-line-update))
 
 (define-obsolete-function-alias
@@ -8482,7 +8463,8 @@ It also looks at the text of the entry itself."
                     (org-get-at-bol 'org-marker)))
         (buffer (and marker (marker-buffer marker)))
         (prefix (buffer-substring (point-at-bol) (point-at-eol)))
-        (lkall (org-offer-links-in-entry buffer marker arg prefix))
+        (lkall (and buffer (org-offer-links-in-entry
+                            buffer marker arg prefix)))
         (lk0 (car lkall))
         (lk (if (stringp lk0) (list lk0) lk0))
         (lkend (cdr lkall))
@@ -8608,7 +8590,8 @@ if it was hidden in the outline."
   (interactive "p")
   (let ((win (selected-window)))
     (org-agenda-goto t)
-    (org-recenter-heading 1)
+    (org-back-to-heading)
+    (set-window-start (selected-window) (point-at-bol))
     (cond
      ((= more 0)
       (hide-subtree)
@@ -8647,11 +8630,6 @@ if it was hidden in the outline."
       (message "Remote: SUBTREE AND ALL DRAWERS")))
     (select-window win)))
 
-(defun org-recenter-heading (n)
-  (save-excursion
-    (org-back-to-heading)
-    (recenter n)))
-
 (defvar org-agenda-cycle-counter nil)
 (defun org-agenda-cycle-show (&optional n)
   "Show the current entry in another window, with default settings.
@@ -8789,8 +8767,12 @@ the same tree node, and the headline of the tree node in the Org-mode file."
          (org-back-to-heading)
          (move-marker org-last-heading-marker (point))))
       (beginning-of-line 1)
-      (save-excursion
+      (save-window-excursion
        (org-agenda-change-all-lines newhead hdmarker 'fixface just-one))
+      (when (org-bound-and-true-p org-clock-out-when-done)
+       (string-match (concat "^" (regexp-opt org-done-keywords-for-agenda))
+                     newhead)
+       (org-agenda-unmark-clocking-task))
       (org-move-to-column col))))
 
 (defun org-agenda-add-note (&optional arg)
@@ -8927,7 +8909,8 @@ Called with a universal prefix arg, show the priority instead of setting it."
     (unless org-enable-priority-commands
       (error "Priority commands are disabled"))
     (org-agenda-check-no-diary)
-    (let* ((marker (or (org-get-at-bol 'org-marker)
+    (let* ((col (current-column))
+          (marker (or (org-get-at-bol 'org-marker)
                       (org-agenda-error)))
           (hdmarker (org-get-at-bol 'org-hd-marker))
           (buffer (marker-buffer hdmarker))
@@ -8946,7 +8929,7 @@ Called with a universal prefix arg, show the priority instead of setting it."
          (end-of-line 1)
          (setq newhead (org-get-heading)))
        (org-agenda-change-all-lines newhead hdmarker)
-       (beginning-of-line 1)))))
+       (org-move-to-column col)))))
 
 ;; FIXME: should fix the tags property of the agenda line.
 (defun org-agenda-set-tags (&optional tag onoff)
@@ -9155,8 +9138,8 @@ Called with a universal prefix arg, show the priority instead of setting it."
       (goto-char (point-max))
       (while (not (bobp))
        (when (equal marker (org-get-at-bol 'org-marker))
-         (org-move-to-column (- (window-width) (length stamp)) t nil t)
-         (org-agenda-fix-tags-filter-overlays-at (point))
+         (remove-text-properties (point-at-bol) (point-at-eol) '(display))
+         (org-move-to-column (- (window-width) (length stamp)) t)
           (if (featurep 'xemacs)
              ;; Use `duplicable' property to trigger undo recording
               (let ((ex (make-extent nil nil))
@@ -9166,9 +9149,9 @@ Called with a universal prefix arg, show the priority instead of setting it."
                  ex (list 'invisible t 'end-glyph gl 'duplicable t))
                 (insert-extent ex (1- (point)) (point-at-eol)))
             (add-text-properties
-             (1- (point)) (point-at-eol)
+            (1- (point)) (point-at-eol)
             (list 'display (org-add-props stamp nil
-                             'face 'secondary-selection))))
+                             'face '(secondary-selection default)))))
          (beginning-of-line 1))
        (beginning-of-line 0)))))
 
@@ -9456,9 +9439,9 @@ a timestamp can be added there."
   (if org-adapt-indentation (org-indent-to-column 2)))
 
 (defun org-agenda-insert-diary-make-new-entry (text)
-  "Make new entry as last child of current entry.
-Add TEXT as headline, and position the cursor in the second line so that
-a timestamp can be added there."
+  "Make a new entry with TEXT as the first child of the current subtree.
+Position the point in the line right after the new heading so
+that a timestamp can be added there."
   (let ((org-show-following-heading t)
        (org-show-siblings t)
        (org-show-hierarchy-above t)
@@ -9614,7 +9597,7 @@ This is a command that has to be installed in `calendar-mode-map'."
             "Hebrew:     " (calendar-hebrew-date-string date) " (until sunset)\n"
             "Islamic:    " (calendar-islamic-date-string date) " (until sunset)\n"
             "French:     " (calendar-french-date-string date) "\n"
-            "Baha'i:     " (calendar-bahai-date-string date) " (until sunset)\n"
+            "Bahá’í:     " (calendar-bahai-date-string date) " (until sunset)\n"
             "Mayan:      " (calendar-mayan-date-string date) "\n"
             "Coptic:     " (calendar-coptic-date-string date) "\n"
             "Ethiopic:   " (calendar-ethiopic-date-string date) "\n"
@@ -9647,7 +9630,7 @@ This is a command that has to be installed in `calendar-mode-map'."
          (overlay-put ov 'type 'org-marked-entry-overlay))
        (end-of-line 1)
        (or (ignore-errors
-             (goto-char (next-single-property-change (point) 'txt)))
+             (goto-char (next-single-property-change (point) 'org-hd-marker)))
            (beginning-of-line 2))
        (while (and (get-char-property (point) 'invisible) (not (eobp)))
          (beginning-of-line 2))
@@ -9665,7 +9648,7 @@ This is a command that has to be installed in `calendar-mode-map'."
   (let ((entries-marked 0) txt-at-point)
     (save-excursion
       (goto-char (point-min))
-      (goto-char (next-single-property-change (point) 'txt))
+      (goto-char (next-single-property-change (point) 'org-hd-marker))
       (while (and (re-search-forward regexp nil t)
                  (setq txt-at-point (get-text-property (point) 'txt)))
        (when (string-match regexp txt-at-point)
@@ -9701,7 +9684,7 @@ This is a command that has to be installed in `calendar-mode-map'."
   (save-excursion
     (goto-char (point-min))
     (while (ignore-errors
-            (goto-char (next-single-property-change (point) 'txt)))
+            (goto-char (next-single-property-change (point) 'org-hd-marker)))
       (org-agenda-bulk-toggle))))
 
 (defun org-agenda-bulk-toggle ()
@@ -9917,31 +9900,43 @@ current HH:MM time."
 
 ;;; Dragging agenda lines forward/backward
 
-(defun org-agenda-drag-line-forward (arg)
-  "Drag an agenda line forward by ARG lines."
+(defun org-agenda-reapply-filters ()
+  "Re-apply all agenda filters."
+  (mapcar
+   (lambda(f) (when (car f) (org-agenda-filter-apply (car f) (cadr f))))
+   `((,org-agenda-tag-filter tag)
+     (,org-agenda-category-filter category)
+     (,org-agenda-regexp-filter regexp)
+     (,(get 'org-agenda-tag-filter :preset-filter) tag)
+     (,(get 'org-agenda-category-filter :preset-filter) category)
+     (,(get 'org-agenda-regexp-filter :preset-filter) regexp))))
+
+(defun org-agenda-drag-line-forward (arg &optional backward)
+  "Drag an agenda line forward by ARG lines.
+When the optional argument `backward' is non-nil, move backward."
   (interactive "p")
-  (let ((inhibit-read-only t) lst)
+  (let ((inhibit-read-only t) lst line)
     (if (or (not (get-text-property (point) 'txt))
            (save-excursion
              (dotimes (n arg)
-               (move-beginning-of-line 2)
+               (move-beginning-of-line (if backward 0 2))
                (push (not (get-text-property (point) 'txt)) lst))
              (delq nil lst)))
        (message "Cannot move line forward")
-      (org-drag-line-forward arg))))
+      (let ((end (save-excursion (move-beginning-of-line 2) (point))))
+       (move-beginning-of-line 1)
+       (setq line (buffer-substring (point) end))
+       (delete-region (point) end)
+       (move-beginning-of-line (funcall (if backward '1- '1+) arg))
+       (insert line)
+       (org-agenda-reapply-filters)
+       (org-agenda-mark-clocking-task)
+       (move-beginning-of-line 0)))))
 
 (defun org-agenda-drag-line-backward (arg)
   "Drag an agenda line backward by ARG lines."
   (interactive "p")
-  (let ((inhibit-read-only t) lst)
-    (if (or (not (get-text-property (point) 'txt))
-           (save-excursion
-             (dotimes (n arg)
-               (move-beginning-of-line 0)
-               (push (not (get-text-property (point) 'txt)) lst))
-             (delq nil lst)))
-       (message "Cannot move line backward")
-      (org-drag-line-backward arg))))
+  (org-agenda-drag-line-forward arg t))
 
 ;;; Flagging notes
 
@@ -10011,10 +10006,10 @@ calling the function returns nil.  This function takes one
 argument: an entry from `org-agenda-get-day-entries'.
 
 FILTER can also be an alist with the car of each cell being
-either 'headline or 'category.  For example:
+either `headline' or `category'.  For example:
 
-  '((headline \"IMPORTANT\")
-    (category \"Work\"))
+  ((headline \"IMPORTANT\")
+   (category \"Work\"))
 
 will only add headlines containing IMPORTANT or headlines
 belonging to the \"Work\" category.