summaryrefslogtreecommitdiff
path: root/elpa/org-9.5.2/org-agenda.el
diff options
context:
space:
mode:
Diffstat (limited to 'elpa/org-9.5.2/org-agenda.el')
-rw-r--r--elpa/org-9.5.2/org-agenda.el10892
1 files changed, 0 insertions, 10892 deletions
diff --git a/elpa/org-9.5.2/org-agenda.el b/elpa/org-9.5.2/org-agenda.el
deleted file mode 100644
index 59bdd5b..0000000
--- a/elpa/org-9.5.2/org-agenda.el
+++ /dev/null
@@ -1,10892 +0,0 @@
-;;; org-agenda.el --- Dynamic task and appointment lists for Org -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2004-2021 Free Software Foundation, Inc.
-
-;; Author: Carsten Dominik <carsten.dominik@gmail.com>
-;; Keywords: outlines, hypermedia, calendar, wp
-;; Homepage: https://orgmode.org
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Commentary:
-
-;; This file contains the code for creating and using the Agenda for Org.
-;;
-;; The functions `org-batch-agenda', `org-batch-agenda-csv', and
-;; `org-batch-store-agenda-views' are implemented as macros to provide
-;; a convenient 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:
-
-(require 'cl-lib)
-(require 'ol)
-(require 'org)
-(require 'org-macs)
-(require 'org-refile)
-
-(declare-function diary-add-to-list "diary-lib"
- (date string specifier &optional marker globcolor literal))
-(declare-function calendar-iso-to-absolute "cal-iso" (date))
-(declare-function calendar-astro-date-string "cal-julian" (&optional date))
-(declare-function calendar-bahai-date-string "cal-bahai" (&optional date))
-(declare-function calendar-chinese-date-string "cal-china" (&optional date))
-(declare-function calendar-coptic-date-string "cal-coptic" (&optional date))
-(declare-function calendar-ethiopic-date-string "cal-coptic" (&optional date))
-(declare-function calendar-french-date-string "cal-french" (&optional date))
-(declare-function calendar-goto-date "cal-move" (date))
-(declare-function calendar-hebrew-date-string "cal-hebrew" (&optional date))
-(declare-function calendar-islamic-date-string "cal-islam" (&optional date))
-(declare-function calendar-iso-date-string "cal-iso" (&optional date))
-(declare-function calendar-iso-from-absolute "cal-iso" (date))
-(declare-function calendar-julian-date-string "cal-julian" (&optional date))
-(declare-function calendar-mayan-date-string "cal-mayan" (&optional date))
-(declare-function calendar-persian-date-string "cal-persia" (&optional date))
-(declare-function calendar-check-holidays "holidays" (date))
-
-(declare-function org-columns-remove-overlays "org-colview" ())
-(declare-function org-datetree-find-date-create "org-datetree"
- (date &optional keep-restriction))
-(declare-function org-columns-quit "org-colview" ())
-(declare-function diary-date-display-form "diary-lib" (&optional type))
-(declare-function org-mobile-write-agenda-for-mobile "org-mobile" (file))
-(declare-function org-habit-insert-consistency-graphs
- "org-habit" (&optional line))
-(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-agenda-columns "org-colview" ())
-(declare-function org-add-archive-files "org-archive" (files))
-(declare-function org-capture "org-capture" (&optional goto keys))
-(declare-function org-clock-modify-effort-estimate "org-clock" (&optional value))
-
-(defvar calendar-mode-map)
-(defvar org-clock-current-task)
-(defvar org-current-tag-alist)
-(defvar org-mobile-force-id-on-agenda-items)
-(defvar org-habit-show-habits)
-(defvar org-habit-show-habits-only-for-today)
-(defvar org-habit-show-all-today)
-(defvar org-habit-scheduled-past-days)
-
-;; Defined somewhere in this file, but used before definition.
-(defvar org-agenda-buffer-name "*Org Agenda*")
-(defvar org-agenda-overriding-header nil)
-(defvar org-agenda-title-append nil)
-;; (with-no-warnings (defvar entry)) ;; unprefixed, from calendar.el
-;; (with-no-warnings (defvar date)) ;; unprefixed, from calendar.el
-(defvar original-date) ; dynamically scoped, calendar.el does scope this
-
-(defvar org-agenda-undo-list nil
- "List of undoable operations in the agenda since last refresh.")
-(defvar org-agenda-pending-undo-list nil
- "In a series of undo commands, this is the list of remaining undo items.")
-
-(defcustom org-agenda-confirm-kill 1
- "When set, remote killing from the agenda buffer needs confirmation.
-When t, a confirmation is always needed. When a number N, confirmation is
-only needed when the text to be killed contains more than N non-white lines."
- :group 'org-agenda
- :type '(choice
- (const :tag "Never" nil)
- (const :tag "Always" t)
- (integer :tag "When more than N lines")))
-
-(defcustom org-agenda-compact-blocks nil
- "Non-nil means make the block agenda more compact.
-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 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)))
-
-(defgroup org-agenda-export nil
- "Options concerning exporting agenda views in Org mode."
- :tag "Org Agenda Export"
- :group 'org-agenda)
-
-(defcustom org-agenda-with-colors t
- "Non-nil means use colors in agenda views."
- :group 'org-agenda-export
- :type 'boolean)
-
-(defcustom org-agenda-exporter-settings nil
- ;; FIXME: Do we really want to evaluate those settings and thus force
- ;; the user to use `quote' all the time?
- "Alist of variable/value pairs that should be active during agenda export.
-This is a good place to set options for ps-print and for htmlize.
-Note that the way this is implemented, the values will be evaluated
-before assigned to the variables. So make sure to quote values you do
-*not* want evaluated, for example
-
- (setq org-agenda-exporter-settings
- \\='((ps-print-color-p \\='black-white)))"
- :group 'org-agenda-export
- :type '(repeat
- (list
- (variable)
- (sexp :tag "Value"))))
-
-(defcustom org-agenda-before-write-hook '(org-agenda-add-entry-text)
- "Hook run in a temporary buffer before writing the agenda to an export file.
-A useful function for this hook is `org-agenda-add-entry-text'."
- :group 'org-agenda-export
- :type 'hook
- :options '(org-agenda-add-entry-text))
-
-(defcustom org-agenda-add-entry-text-maxlines 0
- "Maximum number of entry text lines to be added to agenda.
-This is only relevant when `org-agenda-add-entry-text' is part of
-`org-agenda-before-write-hook', which is the default.
-When this is 0, nothing will happen. When it is greater than 0, it
-specifies the maximum number of lines that will be added for each entry
-that is listed in the agenda view.
-
-Note that this variable is not used during display, only when exporting
-the agenda. For agenda display, see the variables `org-agenda-entry-text-mode'
-and `org-agenda-entry-text-maxlines'."
- :group 'org-agenda
- :type 'integer)
-
-(defcustom org-agenda-add-entry-text-descriptive-links t
- "Non-nil means export org-links as descriptive links in agenda added text.
-This variable applies to the text added to the agenda when
-`org-agenda-add-entry-text-maxlines' is larger than 0.
-When this variable is nil, the URL will (also) be shown."
- :group 'org-agenda
- :type 'boolean)
-
-(defcustom org-agenda-export-html-style nil
- "The style specification for exported HTML Agenda files.
-If this variable contains a string, it will replace the default <style>
-section as produced by `htmlize'.
-Since there are different ways of setting style information, this variable
-needs to contain the full HTML structure to provide a style, including the
-surrounding HTML tags. The style specifications should include definitions
-the fonts used by the agenda, here is an example:
-
- <style type=\"text/css\">
- p { font-weight: normal; color: gray; }
- .org-agenda-structure {
- font-size: 110%;
- color: #003399;
- font-weight: 600;
- }
- .org-todo {
- color: #cc6666;
- font-weight: bold;
- }
- .org-agenda-done {
- color: #339933;
- }
- .org-done {
- color: #339933;
- }
- .title { text-align: center; }
- .todo, .deadline { color: red; }
- .done { color: green; }
- </style>
-
-or, if you want to keep the style in a file,
-
- <link rel=\"stylesheet\" type=\"text/css\" href=\"mystyles.css\">
-
-As the value of this option simply gets inserted into the HTML <head> header,
-you can \"misuse\" it to also add other text to the header."
- :group 'org-agenda-export
- :group 'org-export-html
- :type '(choice
- (const nil)
- (string)))
-
-(defcustom org-agenda-persistent-filter nil
- "When set, keep filters from one agenda view to the next."
- :group 'org-agenda
- :type 'boolean)
-
-(defgroup org-agenda-custom-commands nil
- "Options concerning agenda views in Org mode."
- :tag "Org Agenda Custom Commands"
- :group 'org-agenda)
-
-(defconst org-sorting-choice
- '(choice
- (const time-up) (const time-down)
- (const timestamp-up) (const timestamp-down)
- (const scheduled-up) (const scheduled-down)
- (const deadline-up) (const deadline-down)
- (const ts-up) (const ts-down)
- (const tsia-up) (const tsia-down)
- (const category-keep) (const category-up) (const category-down)
- (const tag-down) (const tag-up)
- (const priority-up) (const priority-down)
- (const todo-state-up) (const todo-state-down)
- (const effort-up) (const effort-down)
- (const habit-up) (const habit-down)
- (const alpha-up) (const alpha-down)
- (const user-defined-up) (const user-defined-down))
- "Sorting choices.")
-
-;; Keep custom values for `org-agenda-filter-preset' compatible with
-;; the new variable `org-agenda-tag-filter-preset'.
-(defvaralias 'org-agenda-filter-preset 'org-agenda-tag-filter-preset)
-(defvaralias 'org-agenda-filter 'org-agenda-tag-filter)
-
-(defvar org-agenda-entry-types '(:deadline :scheduled :timestamp :sexp)
- "List of types searched for when creating the daily/weekly agenda.
-This variable is a list of symbols that controls the types of
-items that appear in the daily/weekly agenda. Allowed symbols in this
-list are
-
- :timestamp List items containing a date stamp or date range matching
- the selected date. This includes sexp entries in angular
- brackets.
-
- :sexp List entries resulting from plain diary-like sexps.
-
- :deadline List deadline due on that date. When the date is today,
- also list any deadlines past due, or due within
- `org-deadline-warning-days'.
-
- :deadline* Same as above, but only include the deadline if it has an
- hour specification as [h]h:mm.
-
- :scheduled List all items which are scheduled for the given date.
- The diary for *today* also contains items which were
- scheduled earlier and are not yet marked DONE.
-
- :scheduled* Same as above, but only include the scheduled item if it
- has an hour specification as [h]h:mm.
-
-By default, all four non-starred types are turned on.
-
-When :scheduled* or :deadline* are included, :schedule or :deadline
-will be ignored.
-
-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 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'.")
-
-(defconst org-agenda-custom-commands-local-options
- `(repeat :tag "Local settings for this command. Remember to quote values"
- (choice :tag "Setting"
- (list :tag "Heading for this block"
- (const org-agenda-overriding-header)
- (string :tag "Headline"))
- (list :tag "Files to be searched"
- (const org-agenda-files)
- (list
- (const :format "" quote)
- (repeat (file))))
- (list :tag "Sorting strategy"
- (const org-agenda-sorting-strategy)
- (list
- (const :format "" quote)
- (repeat
- ,org-sorting-choice)))
- (list :tag "Prefix format"
- (const org-agenda-prefix-format :value " %-12:c%?-12t% s")
- (string))
- (list :tag "Number of days in agenda"
- (const org-agenda-span)
- (list
- (const :format "" quote)
- (choice (const :tag "Day" day)
- (const :tag "Week" week)
- (const :tag "Fortnight" fortnight)
- (const :tag "Month" month)
- (const :tag "Year" year)
- (integer :tag "Custom"))))
- (list :tag "Fixed starting date"
- (const org-agenda-start-day)
- (string :value "2007-11-01"))
- (list :tag "Start on day of week"
- (const org-agenda-start-on-weekday)
- (choice :value 1
- (const :tag "Today" nil)
- (integer :tag "Weekday No.")))
- (list :tag "Include data from diary"
- (const org-agenda-include-diary)
- (boolean))
- (list :tag "Deadline Warning days"
- (const org-deadline-warning-days)
- (integer :value 1))
- (list :tag "Category filter preset"
- (const org-agenda-category-filter-preset)
- (list
- (const :format "" quote)
- (repeat
- (string :tag "+category or -category"))))
- (list :tag "Tags filter preset"
- (const org-agenda-tag-filter-preset)
- (list
- (const :format "" quote)
- (repeat
- (string :tag "+tag or -tag"))))
- (list :tag "Effort filter preset"
- (const org-agenda-effort-filter-preset)
- (list
- (const :format "" quote)
- (repeat
- (string :tag "+=10 or -=10 or +<10 or ->10"))))
- (list :tag "Regexp filter preset"
- (const org-agenda-regexp-filter-preset)
- (list
- (const :format "" quote)
- (repeat
- (string :tag "+regexp or -regexp"))))
- (list :tag "Set daily/weekly entry types"
- (const org-agenda-entry-types)
- (list
- (const :format "" quote)
- (set :greedy t :value ,org-agenda-entry-types
- (const :deadline)
- (const :scheduled)
- (const :deadline*)
- (const :scheduled*)
- (const :timestamp)
- (const :sexp))))
- (list :tag "Columns format"
- (const org-overriding-columns-format)
- (string :tag "Format"))
- (list :tag "Standard skipping condition"
- :value (org-agenda-skip-function '(org-agenda-skip-entry-if))
- (const org-agenda-skip-function)
- (list
- (const :format "" quote)
- (list
- (choice
- :tag "Skipping range"
- (const :tag "Skip entry" org-agenda-skip-entry-if)
- (const :tag "Skip subtree" org-agenda-skip-subtree-if))
- (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 "TODO state is" :inline t
- (const todo)
- (choice
- (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)
- (choice
- (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))))))
- (list :tag "Non-standard skipping condition"
- :value (org-agenda-skip-function)
- (const org-agenda-skip-function)
- (sexp :tag "Function or form (quoted!)"))
- (list :tag "Any variable"
- (variable :tag "Variable")
- (sexp :tag "Value (sexp)"))))
- "Selection of examples for agenda command settings.
-This will be spliced into the custom type of
-`org-agenda-custom-commands'.")
-
-
-(defcustom org-agenda-custom-commands
- '(("n" "Agenda and all TODOs" ((agenda "") (alltodo ""))))
- "Custom commands for the agenda.
-\\<org-mode-map>
-These commands will be offered on the splash screen displayed by the
-agenda dispatcher `\\[org-agenda]'. Each entry is a list like this:
-
- (key desc type match settings files)
-
-key The key (one or more characters as a string) to be associated
- with the command.
-desc A description of the command, when omitted or nil, a default
- description is built using MATCH.
-type The command type, any of the following symbols:
- agenda The daily/weekly agenda.
- todo Entries with a specific TODO keyword, in all agenda files.
- search Entries containing search words entry or headline.
- tags Tags/Property/TODO match in all agenda files.
- tags-todo Tags/P/T match in all agenda files, TODO entries only.
- todo-tree Sparse tree of specific TODO keyword in *current* file.
- tags-tree Sparse tree with all tags matches in *current* file.
- occur-tree Occur sparse tree for *current* file.
- ... A user-defined function.
-match What to search for:
- - a single keyword for TODO keyword searches
- - a tags/property/todo match expression for searches
- - a word search expression for text searches.
- - a regular expression for occur searches
- For all other commands, this should be the empty string.
-settings A list of option settings, similar to that in a let form, so like
- this: ((opt1 val1) (opt2 val2) ...). The values will be
- evaluated at the moment of execution, so quote them when needed.
-files A list of files to write the produced agenda buffer to with
- the command `org-store-agenda-views'.
- If a file name ends in \".html\", an HTML version of the buffer
- is written out. If it ends in \".ps\", a postscript version is
- produced. Otherwise, only the plain text is written to the file.
-
-You can also define a set of commands, to create a composite agenda buffer.
-In this case, an entry looks like this:
-
- (key desc (cmd1 cmd2 ...) general-settings-for-whole-set files)
-
-where
-
-desc A description string to be displayed in the dispatcher menu.
-cmd An agenda command, similar to the above. However, tree commands
- are not allowed, but instead you can get agenda and global todo list.
- So valid commands for a set are:
- (agenda \"\" settings)
- (alltodo \"\" settings)
- (stuck \"\" settings)
- (todo \"match\" settings files)
- (search \"match\" settings files)
- (tags \"match\" settings files)
- (tags-todo \"match\" settings files)
-
-Each command can carry a list of options, and another set of options can be
-given for the whole set of commands. Individual command options take
-precedence over the general options.
-
-When using several characters as key to a command, the first characters
-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\"
- (\"hl\" tags \"+HOME+Lisa\")
- (\"hp\" tags \"+HOME+Peter\")
- (\"hk\" tags \"+HOME+Kim\")))"
- :group 'org-agenda-custom-commands
- :type `(repeat
- (choice :value ("x" "Describe command here" tags "" nil)
- (list :tag "Single command"
- (string :tag "Access Key(s) ")
- (option (string :tag "Description"))
- (choice
- (const :tag "Agenda" agenda)
- (const :tag "TODO list" alltodo)
- (const :tag "Search words" search)
- (const :tag "Stuck projects" stuck)
- (const :tag "Tags/Property match (all agenda files)" tags)
- (const :tag "Tags/Property match of TODO entries (all agenda files)" tags-todo)
- (const :tag "TODO keyword search (all agenda files)" todo)
- (const :tag "Tags sparse tree (current buffer)" tags-tree)
- (const :tag "TODO keyword tree (current buffer)" todo-tree)
- (const :tag "Occur tree (current buffer)" occur-tree)
- (sexp :tag "Other, user-defined function"))
- (string :tag "Match (only for some commands)")
- ,org-agenda-custom-commands-local-options
- (option (repeat :tag "Export" (file :tag "Export to"))))
- (list :tag "Command series, all agenda files"
- (string :tag "Access Key(s)")
- (string :tag "Description ")
- (repeat :tag "Component"
- (choice
- (list :tag "Agenda"
- (const :format "" agenda)
- (const :tag "" :format "" "")
- ,org-agenda-custom-commands-local-options)
- (list :tag "TODO list (all keywords)"
- (const :format "" alltodo)
- (const :tag "" :format "" "")
- ,org-agenda-custom-commands-local-options)
- (list :tag "Search words"
- (const :format "" search)
- (string :tag "Match")
- ,org-agenda-custom-commands-local-options)
- (list :tag "Stuck projects"
- (const :format "" stuck)
- (const :tag "" :format "" "")
- ,org-agenda-custom-commands-local-options)
- (list :tag "Tags/Property match (all agenda files)"
- (const :format "" tags)
- (string :tag "Match")
- ,org-agenda-custom-commands-local-options)
- (list :tag "Tags/Property match of TODO entries (all agenda files)"
- (const :format "" tags-todo)
- (string :tag "Match")
- ,org-agenda-custom-commands-local-options)
- (list :tag "TODO keyword search"
- (const :format "" todo)
- (string :tag "Match")
- ,org-agenda-custom-commands-local-options)
- (list :tag "Other, user-defined function"
- (symbol :tag "function")
- (string :tag "Match")
- ,org-agenda-custom-commands-local-options)))
-
- (repeat :tag "Settings for entire command set"
- (list (variable :tag "Any variable")
- (sexp :tag "Value")))
- (option (repeat :tag "Export" (file :tag "Export to"))))
- (cons :tag "Prefix key documentation"
- (string :tag "Access Key(s)")
- (string :tag "Description ")))))
-
-(defcustom org-agenda-query-register ?o
- "The register holding the current query string.
-The purpose of this is that if you construct a query string interactively,
-you can then use it to define a custom command."
- :group 'org-agenda-custom-commands
- :type 'character)
-
-(defcustom org-stuck-projects
- '("+LEVEL=2/-DONE" ("TODO" "NEXT" "NEXTACTION") nil "")
- "How to identify stuck projects.
-This is a list of four items:
-1. A tags/todo/property matcher string that is used to identify a project.
- See the manual for a description of tag and property searches.
- The entire tree below a headline matched by this is considered one project.
-2. A list of TODO keywords identifying non-stuck projects.
- If the project subtree contains any headline with one of these todo
- keywords, the project is considered to be not stuck. If you specify
- \"*\" as a keyword, any TODO keyword will mark the project unstuck.
-3. A list of tags identifying non-stuck projects.
- If the project subtree contains any headline with one of these tags,
- the project is considered to be not stuck. If you specify \"*\" as
- a tag, any tag will mark the project unstuck. Note that this is about
- the explicit presence of a tag somewhere in the subtree, inherited
- tags do not count here. If inherited tags make a project not stuck,
- use \"-TAG\" in the tags part of the matcher under (1.) above.
-4. An arbitrary regular expression matching non-stuck projects.
-
-If the project turns out to be not stuck, search continues also in the
-subtree to see if any of the subtasks have project status.
-
-See also the variable `org-tags-match-list-sublevels' which applies
-to projects matched by this search as well.
-
-After defining this variable, you may use `org-agenda-list-stuck-projects'
-\(bound to `\\[org-agenda] #') to produce the list."
- :group 'org-agenda-custom-commands
- :type '(list
- (string :tag "Tags/TODO match to identify a project")
- (repeat :tag "Projects are *not* stuck if they have an entry with \
-TODO keyword any of" (string))
- (repeat :tag "Projects are *not* stuck if they have an entry with \
-TAG being any of" (string))
- (regexp :tag "Projects are *not* stuck if this regexp matches inside \
-the subtree")))
-
-(defgroup org-agenda-skip nil
- "Options concerning skipping parts of agenda files."
- :tag "Org Agenda Skip"
- :group 'org-agenda)
-
-(defcustom org-agenda-skip-function-global nil
- "Function to be called at each match during agenda construction.
-If this function returns nil, the current match should not be skipped.
-If the function decided to skip an agenda match, is must return the
-buffer position from which the search should be continued.
-This may also be a Lisp form, which will be evaluated.
-
-This variable will be applied to every agenda match, including
-tags/property searches and TODO lists. So try to make the test function
-do its checking as efficiently as possible. To implement a skipping
-condition just for specific agenda commands, use the variable
-`org-agenda-skip-function' which can be set in the options section
-of custom agenda commands."
- :group 'org-agenda-skip
- :type 'sexp)
-
-(defgroup org-agenda-daily/weekly nil
- "Options concerning the daily/weekly agenda."
- :tag "Org Agenda Daily/Weekly"
- :group 'org-agenda)
-(defgroup org-agenda-todo-list nil
- "Options concerning the global todo list agenda view."
- :tag "Org Agenda Todo List"
- :group 'org-agenda)
-(defgroup org-agenda-match-view nil
- "Options concerning the general tags/property/todo match agenda view."
- :tag "Org Agenda Match View"
- :group 'org-agenda)
-(defgroup org-agenda-search-view nil
- "Options concerning the search agenda view."
- :tag "Org Agenda Search View"
- :group 'org-agenda)
-
-(defvar org-agenda-archives-mode nil
- "Non-nil means the agenda will include archived items.
-If this is the symbol `trees', trees in the selected agenda scope
-that are marked with the ARCHIVE tag will be included anyway. When this is
-t, also all archive files associated with the current selection of agenda
-files will be included.")
-
-(defcustom org-agenda-restriction-lock-highlight-subtree t
- "Non-nil means highlight the whole subtree when restriction is active.
-Otherwise only highlight the headline. Highlighting the whole subtree is
-useful to ensure no edits happen beyond the restricted region."
- :group 'org-agenda
- :type 'boolean)
-
-(defcustom org-agenda-skip-comment-trees t
- "Non-nil means skip trees that start with the COMMENT keyword.
-When nil, these trees are also scanned by agenda commands."
- :group 'org-agenda-skip
- :type 'boolean)
-
-(defcustom org-agenda-todo-list-sublevels t
- "Non-nil means check also the sublevels of a TODO entry for TODO entries.
-When nil, the sublevels of a TODO entry are not checked, resulting in
-potentially much shorter TODO lists."
- :group 'org-agenda-skip
- :group 'org-agenda-todo-list
- :type 'boolean)
-
-(defcustom org-agenda-todo-ignore-with-date nil
- "Non-nil means don't show entries with a date in the global todo list.
-You can use this if you prefer to mark mere appointments with a TODO keyword,
-but don't want them to show up in the TODO list.
-When this is set, it also covers deadlines and scheduled items, the settings
-of `org-agenda-todo-ignore-scheduled' and `org-agenda-todo-ignore-deadlines'
-will be ignored.
-See also the variable `org-agenda-tags-todo-honor-ignore-options'."
- :group 'org-agenda-skip
- :group 'org-agenda-todo-list
- :type 'boolean)
-
-(defcustom org-agenda-todo-ignore-timestamp nil
- "Non-nil means don't show entries with a timestamp.
-This applies when creating the global todo list.
-Valid values are:
-
-past Don't show entries for today or in the past.
-
-future Don't show entries with a timestamp in the future.
- The idea behind this is that if it has a future
- timestamp, you don't want to think about it until the
- date.
-
-all Don't show any entries with a timestamp in the global todo list.
- The idea behind this is that by setting a timestamp, you
- have already \"taken care\" of this item.
-
-This variable can also have an integer as a value. If positive (N),
-todos with a timestamp N or more days in the future will be ignored. If
-negative (-N), todos with a timestamp N or more days in the past will be
-ignored. If 0, todos with a timestamp either today or in the future will
-be ignored. For example, a value of -1 will exclude todos with a
-timestamp in the past (yesterday or earlier), while a value of 7 will
-exclude todos with a timestamp a week or more in the future.
-
-See also `org-agenda-todo-ignore-with-date'.
-See also the variable `org-agenda-tags-todo-honor-ignore-options' if you want
-to make his option also apply to the tags-todo list."
- :group 'org-agenda-skip
- :group 'org-agenda-todo-list
- :version "24.1"
- :type '(choice
- (const :tag "Ignore future timestamp todos" future)
- (const :tag "Ignore past or present timestamp todos" past)
- (const :tag "Ignore all timestamp todos" all)
- (const :tag "Show timestamp todos" nil)
- (integer :tag "Ignore if N or more days in past(-) or future(+).")))
-
-(defcustom org-agenda-todo-ignore-scheduled nil
- "Non-nil means, ignore some scheduled TODO items when making TODO list.
-This applies when creating the global todo list.
-Valid values are:
-
-past Don't show entries scheduled today or in the past.
-
-future Don't show entries scheduled in the future.
- The idea behind this is that by scheduling it, you don't want to
- think about it until the scheduled date.
-
-all Don't show any scheduled entries in the global todo list.
- The idea behind this is that by scheduling it, you have already
- \"taken care\" of this item.
-
-t Same as `all', for backward compatibility.
-
-This variable can also have an integer as a value. See
-`org-agenda-todo-ignore-timestamp' for more details.
-
-See also `org-agenda-todo-ignore-with-date'.
-See also the variable `org-agenda-tags-todo-honor-ignore-options' if you want
-to make his option also apply to the tags-todo list."
- :group 'org-agenda-skip
- :group 'org-agenda-todo-list
- :type '(choice
- (const :tag "Ignore future-scheduled todos" future)
- (const :tag "Ignore past- or present-scheduled todos" past)
- (const :tag "Ignore all scheduled todos" all)
- (const :tag "Ignore all scheduled todos (compatibility)" t)
- (const :tag "Show scheduled todos" nil)
- (integer :tag "Ignore if N or more days in past(-) or future(+).")))
-
-(defcustom org-agenda-todo-ignore-deadlines nil
- "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.
-
-This applies when creating the global TODO list.
-
-Valid values are:
-
-near Don't show near deadline entries. A deadline is near when it is
- closer than `org-deadline-warning-days' days. The idea behind this
- is that such items will appear in the agenda anyway.
-
-far Don't show TODO entries where a deadline has been defined, but
- is not going to happen anytime soon. This is useful if you want to use
- the TODO list to figure out what to do now.
-
-past Don't show entries with a deadline timestamp for today or in the past.
-
-future Don't show entries with a deadline timestamp in the future, not even
- when they become `near' ones. Use it with caution.
-
-all Ignore all TODO entries that do have a deadline.
-
-t Same as `near', for backward compatibility.
-
-This variable can also have an integer as a value. See
-`org-agenda-todo-ignore-timestamp' for more details.
-
-See also `org-agenda-todo-ignore-with-date'.
-See also the variable `org-agenda-tags-todo-honor-ignore-options' if you want
-to make his option also apply to the tags-todo list."
- :group 'org-agenda-skip
- :group 'org-agenda-todo-list
- :type '(choice
- (const :tag "Ignore near deadlines" near)
- (const :tag "Ignore near deadlines (compatibility)" t)
- (const :tag "Ignore far deadlines" far)
- (const :tag "Ignore all TODOs with a deadlines" all)
- (const :tag "Show all TODOs, even if they have a deadline" nil)
- (integer :tag "Ignore if N or more days in past(-) or future(+).")))
-
-(defcustom org-agenda-todo-ignore-time-comparison-use-seconds nil
- "Time unit to use when possibly ignoring an agenda item.
-
-See the docstring of various `org-agenda-todo-ignore-*' options.
-The default is to compare time stamps using days. An item is thus
-considered to be in the future if it is at least one day after today.
-Non-nil means to compare time stamps using seconds. An item is then
-considered future if it has a time value later than current time."
- :group 'org-agenda-skip
- :group 'org-agenda-todo-list
- :version "24.4"
- :package-version '(Org . "8.0")
- :type '(choice
- (const :tag "Compare time with days" nil)
- (const :tag "Compare time with seconds" t)))
-
-(defcustom org-agenda-tags-todo-honor-ignore-options nil
- "Non-nil means honor todo-list ignores options also in tags-todo search.
-The variables
- `org-agenda-todo-ignore-with-date',
- `org-agenda-todo-ignore-timestamp',
- `org-agenda-todo-ignore-scheduled',
- `org-agenda-todo-ignore-deadlines'
-make the global TODO list skip entries that have time stamps of certain
-kinds. If this option is set, the same options will also apply for the
-tags-todo search, which is the general tags/property matcher
-restricted to unfinished TODO entries only."
- :group 'org-agenda-skip
- :group 'org-agenda-todo-list
- :group 'org-agenda-match-view
- :type 'boolean)
-
-(defcustom org-agenda-skip-scheduled-if-done nil
- "Non-nil means don't show scheduled items in agenda when they are done.
-This is relevant for the daily/weekly agenda, not for the TODO list. It
-applies only to the actual date of the scheduling. Warnings about an item
-with a past scheduling dates are always turned off when the item is DONE."
- :group 'org-agenda-skip
- :group 'org-agenda-daily/weekly
- :type 'boolean)
-
-(defcustom org-agenda-skip-scheduled-if-deadline-is-shown nil
- "Non-nil means skip scheduling line if same entry shows because of deadline.
-
-In the agenda of today, an entry can show up multiple times
-because it is both scheduled and has a nearby deadline, and maybe
-a plain time stamp as well.
-
-When this variable is nil, the entry will be shown several times.
-
-When set to t, then only the deadline is shown and the fact that
-the entry is scheduled today or was scheduled previously is not
-shown.
-
-When set to the symbol `not-today', skip scheduled previously,
-but not scheduled today.
-
-When set to the symbol `repeated-after-deadline', skip scheduled
-items if they are repeated beyond the current deadline."
- :group 'org-agenda-skip
- :group 'org-agenda-daily/weekly
- :type '(choice
- (const :tag "Never" nil)
- (const :tag "Always" t)
- (const :tag "Not when scheduled today" not-today)
- (const :tag "When repeated past deadline" repeated-after-deadline)))
-
-(defcustom org-agenda-skip-timestamp-if-deadline-is-shown nil
- "Non-nil means skip timestamp line if same entry shows because of deadline.
-In the agenda of today, an entry can show up multiple times
-because it has both a plain timestamp and has a nearby deadline.
-When this variable is t, then only the deadline is shown and the
-fact that the entry has a timestamp for or including today is not
-shown. When this variable is nil, the entry will be shown
-several times."
- :group 'org-agenda-skip
- :group 'org-agenda-daily/weekly
- :version "24.1"
- :type '(choice
- (const :tag "Never" nil)
- (const :tag "Always" t)))
-
-(defcustom org-agenda-skip-deadline-if-done nil
- "Non-nil means don't show deadlines when the corresponding item is done.
-When nil, the deadline is still shown and should give you a happy feeling.
-This is relevant for the daily/weekly agenda. It applies only to the
-actual date of the deadline. Warnings about approaching and past-due
-deadlines are always turned off when the item is DONE."
- :group 'org-agenda-skip
- :group 'org-agenda-daily/weekly
- :type 'boolean)
-
-(defcustom org-agenda-skip-deadline-prewarning-if-scheduled nil
- "Non-nil means skip deadline prewarning when entry is also scheduled.
-This will apply on all days where a prewarning for the deadline would
-be shown, but not at the day when the entry is actually due. On that day,
-the deadline will be shown anyway.
-This variable may be set to nil, t, the symbol `pre-scheduled',
-or a number which will then give the number of days before the actual
-deadline when the prewarnings should resume. The symbol `pre-scheduled'
-eliminates the deadline prewarning only prior to the scheduled date.
-This can be used in a workflow where the first showing of the deadline will
-trigger you to schedule it, and then you don't want to be reminded of it
-because you will take care of it on the day when scheduled."
- :group 'org-agenda-skip
- :group 'org-agenda-daily/weekly
- :version "24.1"
- :type '(choice
- (const :tag "Always show prewarning" nil)
- (const :tag "Remove prewarning prior to scheduled date" pre-scheduled)
- (const :tag "Remove prewarning if entry is scheduled" t)
- (integer :tag "Restart prewarning N days before deadline")))
-
-(defcustom org-agenda-skip-scheduled-delay-if-deadline nil
- "Non-nil means skip scheduled delay when entry also has a deadline.
-This variable may be set to nil, t, the symbol `post-deadline',
-or a number which will then give the number of days after the actual
-scheduled date when the delay should expire. The symbol `post-deadline'
-eliminates the schedule delay when the date is posterior to the deadline."
- :group 'org-agenda-skip
- :group 'org-agenda-daily/weekly
- :version "24.4"
- :package-version '(Org . "8.0")
- :type '(choice
- (const :tag "Always honor delay" nil)
- (const :tag "Ignore delay if posterior to the deadline" post-deadline)
- (const :tag "Ignore delay if entry has a deadline" t)
- (integer :tag "Honor delay up until N days after the scheduled date")))
-
-(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."
- :group 'org-agenda-skip
- :type 'boolean)
-
-(defcustom org-agenda-skip-timestamp-if-done nil
- "Non-nil means don't select item by timestamp or -range if it is DONE."
- :group 'org-agenda-skip
- :group 'org-agenda-daily/weekly
- :type 'boolean)
-
-(defcustom org-agenda-dim-blocked-tasks t
- "Non-nil means dim blocked tasks in the agenda display.
-This causes some overhead during agenda construction, but if you
-have turned on `org-enforce-todo-dependencies',
-`org-enforce-todo-checkbox-dependencies', or any other blocking
-mechanism, this will create useful feedback in the agenda.
-
-Instead of t, this variable can also have the value `invisible'.
-Then blocked tasks will be invisible and only become visible when
-they become unblocked. An exemption to this behavior is when a task is
-blocked because of unchecked checkboxes below it. Since checkboxes do
-not show up in the agenda views, making this task invisible you remove any
-trace from agenda views that there is something to do. Therefore, a task
-that is blocked because of checkboxes will never be made invisible, it
-will only be dimmed."
- :group 'org-agenda-daily/weekly
- :group 'org-agenda-todo-list
- :version "24.3"
- :type '(choice
- (const :tag "Do not dim" nil)
- (const :tag "Dim to a gray face" t)
- (const :tag "Make invisible" invisible)))
-
-(defgroup org-agenda-startup nil
- "Options concerning initial settings in the Agenda in Org Mode."
- :tag "Org Agenda Startup"
- :group 'org-agenda)
-
-(defcustom org-agenda-menu-show-matcher t
- "Non-nil means show the match string in the agenda dispatcher menu.
-When nil, the matcher string is not shown, but is put into the help-echo
-property so than moving the mouse over the command shows it.
-Setting it to nil is good if matcher strings are very long and/or if
-you want to use two-columns display (see `org-agenda-menu-two-columns')."
- :group 'org-agenda
- :version "24.1"
- :type 'boolean)
-
-(defcustom org-agenda-menu-two-columns nil
- "Non-nil means, use two columns to show custom commands in the dispatcher.
-If you use this, you probably want to set `org-agenda-menu-show-matcher'
-to nil."
- :group 'org-agenda
- :version "24.1"
- :type 'boolean)
-
-(defcustom org-agenda-finalize-hook nil
- "Hook run just before displaying an agenda buffer.
-The buffer is still writable when the hook is called.
-
-You can modify some of the buffer substrings but you should be
-extra careful not to modify the text properties of the agenda
-headlines as the agenda display heavily relies on them."
- :group 'org-agenda-startup
- :type 'hook)
-
-(defcustom org-agenda-filter-hook nil
- "Hook run just after filtering with `org-agenda-filter'."
- :group 'org-agenda-startup
- :package-version '(Org . "9.4")
- :type 'hook)
-
-(defcustom org-agenda-mouse-1-follows-link nil
- "Non-nil means mouse-1 on a link will follow the link in the agenda.
-A longer mouse click will still set point. Needs to be set
-before org.el is loaded."
- :group 'org-agenda-startup
- :type 'boolean)
-
-(defcustom org-agenda-start-with-follow-mode nil
- "The initial value of follow mode in a newly created agenda window."
- :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
- :version "24.1"
- :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
- :type 'boolean)
-
-(defcustom org-agenda-start-with-entry-text-mode nil
- "The initial value of entry-text-mode in a newly created agenda window."
- :group 'org-agenda-startup
- :type 'boolean)
-
-(defcustom org-agenda-entry-text-maxlines 5
- "Number of text lines to be added when `E' is pressed in the agenda.
-
-Note that this variable only used during agenda display. To add entry text
-when exporting the agenda, configure the variable
-`org-agenda-add-entry-text-maxlines'."
- :group 'org-agenda
- :type 'integer)
-
-(defcustom org-agenda-entry-text-exclude-regexps nil
- "List of regular expressions to clean up entry text.
-The complete matches of all regular expressions in this list will be
-removed from entry text before it is shown in the agenda."
- :group 'org-agenda
- :type '(repeat (regexp)))
-
-(defcustom org-agenda-entry-text-leaders " > "
- "Text prepended to the entry text in agenda buffers."
- :version "24.4"
- :package-version '(Org . "8.0")
- :group 'org-agenda
- :type 'string)
-
-(defvar org-agenda-entry-text-cleanup-hook nil
- "Hook that is run after basic cleanup of entry text to be shown in agenda.
-This cleanup is done in a temporary buffer, so the function may inspect and
-change the entire buffer.
-Some default stuff like drawers and scheduling/deadline dates will already
-have been removed when this is called, as will any matches for regular
-expressions listed in `org-agenda-entry-text-exclude-regexps'.")
-
-(defvar org-agenda-include-inactive-timestamps nil
- "Non-nil means include inactive time stamps in agenda.
-Dynamically scoped.")
-
-(defgroup org-agenda-windows nil
- "Options concerning the windows used by the Agenda in Org Mode."
- :tag "Org Agenda Windows"
- :group 'org-agenda)
-
-(defcustom org-agenda-window-setup 'reorganize-frame
- "How the agenda buffer should be displayed.
-Possible values for this option are:
-
-current-window Show agenda in the current window, keeping all other windows.
-other-window Use `switch-to-buffer-other-window' to display agenda.
-only-window Show agenda, deleting all other windows.
-reorganize-frame Show only two windows on the current frame, the current
- window and the agenda.
-other-frame Use `switch-to-buffer-other-frame' to display agenda.
- Also, when exiting the agenda, kill that frame.
-other-tab Use `switch-to-buffer-other-tab' to display the
- agenda, making use of the `tab-bar-mode' introduced
- in Emacs version 27.1. Also, kill that tab when
- exiting the agenda view.
-
-See also the variable `org-agenda-restore-windows-after-quit'."
- :group 'org-agenda-windows
- :type '(choice
- (const current-window)
- (const other-frame)
- (const other-tab)
- (const other-window)
- (const only-window)
- (const reorganize-frame))
- :package-version '(Org . "9.4"))
-
-(defcustom org-agenda-window-frame-fractions '(0.5 . 0.75)
- "The min and max height of the agenda window as a fraction of frame height.
-The value of the variable is a cons cell with two numbers between 0 and 1.
-It only matters if `org-agenda-window-setup' is `reorganize-frame'."
- :group 'org-agenda-windows
- :type '(cons (number :tag "Minimum") (number :tag "Maximum")))
-
-(defcustom org-agenda-restore-windows-after-quit nil
- "Non-nil means restore window configuration upon exiting agenda.
-Before the window configuration is changed for displaying the
-agenda, the current status is recorded. When the agenda is
-exited with `q' or `x' and this option is set, the old state is
-restored. If `org-agenda-window-setup' is `other-frame' or
-`other-tab', the value of this option will be ignored."
- :group 'org-agenda-windows
- :type 'boolean)
-
-(defcustom org-agenda-span 'week
- "Number of days to include in overview display.
-Can be day, week, month, year, or any number of days.
-Custom commands can set this variable in the options section."
- :group 'org-agenda-daily/weekly
- :type '(choice (const :tag "Day" day)
- (const :tag "Week" week)
- (const :tag "Fortnight" fortnight)
- (const :tag "Month" month)
- (const :tag "Year" year)
- (integer :tag "Custom")))
-
-(defcustom org-agenda-start-on-weekday 1
- "Non-nil means start the overview always on the specified weekday.
-0 denotes Sunday, 1 denotes Monday, etc.
-When nil, always start on the current day.
-Custom commands can set this variable in the options section."
- :group 'org-agenda-daily/weekly
- :type '(choice (const :tag "Today" nil)
- (integer :tag "Weekday No.")))
-
-(defcustom org-agenda-show-all-dates t
- "Non-nil means `org-agenda' shows every day in the selected range.
-When nil, only the days which actually have entries are shown."
- :group 'org-agenda-daily/weekly
- :type 'boolean)
-
-(defcustom org-agenda-format-date 'org-agenda-format-date-aligned
- "Format string for displaying dates in the agenda.
-Used by the daily/weekly agenda. This should be a format string
-understood by `format-time-string', or a function returning the
-formatted date as a string. The function must take a single
-argument, a calendar-style date list like (month day year)."
- :group 'org-agenda-daily/weekly
- :type '(choice
- (string :tag "Format string")
- (function :tag "Function")))
-
-(defun org-agenda-end-of-line ()
- "Go to the end of visible line."
- (interactive)
- (goto-char (line-end-position)))
-
-(defun org-agenda-format-date-aligned (date)
- "Format a DATE string for display in the daily/weekly agenda.
-This function makes sure that dates are aligned for easy reading."
- (require 'cal-iso)
- (let* ((dayname (calendar-day-name date))
- (day (cadr date))
- (day-of-week (calendar-day-of-week date))
- (month (car date))
- (monthname (calendar-month-name month))
- (year (nth 2 date))
- (iso-week (org-days-to-iso-week
- (calendar-absolute-from-gregorian date)))
- ;; (weekyear (cond ((and (= month 1) (>= iso-week 52))
- ;; (1- year))
- ;; ((and (= month 12) (<= iso-week 1))
- ;; (1+ year))
- ;; (t year)))
- (weekstring (if (= day-of-week 1)
- (format " W%02d" iso-week)
- "")))
- (format "%-10s %2d %s %4d%s"
- dayname day monthname year weekstring)))
-
-(defcustom org-agenda-time-leading-zero nil
- "Non-nil means use leading zero for military times in agenda.
-For example, 9:30am would become 09:30 rather than 9:30."
- :group 'org-agenda-daily/weekly
- :version "24.1"
- :type 'boolean)
-
-(defcustom org-agenda-timegrid-use-ampm nil
- "When set, show AM/PM style timestamps on the timegrid."
- :group 'org-agenda
- :version "24.1"
- :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."
- (let* ((hour-number (string-to-number (substring time 0 -3)))
- (minute (substring time -2))
- (ampm "am"))
- (cond
- ((equal hour-number 12)
- (setq ampm "pm"))
- ((> hour-number 12)
- (setq ampm "pm")
- (setq hour-number (- hour-number 12))))
- (concat
- (if org-agenda-time-leading-zero
- (format "%02d" hour-number)
- (format "%02s" (number-to-string hour-number)))
- ":" minute ampm)))
-
-(defun org-agenda-time-of-day-to-ampm-maybe (time)
- "Conditionally convert TIME to AM/PM format.
-This is based on `org-agenda-timegrid-use-ampm'."
- (if org-agenda-timegrid-use-ampm
- (org-agenda-time-of-day-to-ampm time)
- time))
-
-(defcustom org-agenda-weekend-days '(6 0)
- "Which days are weekend?
-These days get the special face `org-agenda-date-weekend' in the agenda."
- :group 'org-agenda-daily/weekly
- :type '(set :greedy t
- (const :tag "Monday" 1)
- (const :tag "Tuesday" 2)
- (const :tag "Wednesday" 3)
- (const :tag "Thursday" 4)
- (const :tag "Friday" 5)
- (const :tag "Saturday" 6)
- (const :tag "Sunday" 0)))
-
-(defcustom org-agenda-move-date-from-past-immediately-to-today t
- "Non-nil means jump to today when moving a past date forward in time.
-When using S-right in the agenda to move 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
- :version "24.1"
- :type 'boolean)
-
-(defcustom org-agenda-diary-file 'diary-file
- "File to which to add new entries with the `i' key in agenda and calendar.
-When this is the symbol `diary-file', the functionality in the Emacs
-calendar will be used to add entries to the `diary-file'. But when this
-points to a file, `org-agenda-diary-entry' will be used instead."
- :group 'org-agenda
- :type '(choice
- (const :tag "The standard Emacs diary file" diary-file)
- (file :tag "Special Org file diary entries")))
-
-(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."
- :group 'org-agenda-daily/weekly
- :type 'boolean)
-
-(defcustom org-agenda-include-deadlines t
- "If non-nil, include entries within their deadline warning period.
-Custom commands can set this variable in the options section."
- :group 'org-agenda-daily/weekly
- :version "24.1"
- :type 'boolean)
-
-(defcustom org-agenda-show-future-repeats t
- "Non-nil shows repeated entries in the future part of the agenda.
-When set to the symbol `next' only the first future repeat is shown."
- :group 'org-agenda-daily/weekly
- :type '(choice
- (const :tag "Show all repeated entries" t)
- (const :tag "Show next repeated entry" next)
- (const :tag "Do not show repeated entries" nil))
- :version "26.1"
- :package-version '(Org . "9.1")
- :safe #'symbolp)
-
-(defcustom org-agenda-prefer-last-repeat nil
- "Non-nil sets date for repeated entries to their last repeat.
-
-When nil, display SCHEDULED and DEADLINE dates at their base
-date, and in today's agenda, as a reminder. Display plain
-time-stamps, on the other hand, at every repeat date in the past
-in addition to the base date.
-
-When non-nil, show a repeated entry at its latest repeat date,
-possibly being today even if it wasn't marked as done. This
-setting is useful if you do not always mark repeated entries as
-done and, yet, consider that reaching repeat date starts the task
-anew.
-
-When set to a list of strings, prefer last repeats only for
-entries with these TODO keywords."
- :group 'org-agenda-daily/weekly
- :type '(choice
- (const :tag "Prefer last repeat" t)
- (const :tag "Prefer base date" nil)
- (repeat :tag "Prefer last repeat for entries with these TODO keywords"
- (string :tag "TODO keyword")))
- :version "26.1"
- :package-version '(Org . "9.1")
- :safe (lambda (x) (or (booleanp x) (consp x))))
-
-(defcustom org-scheduled-past-days 10000
- "Number of days to continue listing scheduled items not marked DONE.
-When an item is scheduled on a date, it shows up in the agenda on
-this day and will be listed until it is marked done or for the
-number of days given here."
- :group 'org-agenda-daily/weekly
- :type 'integer
- :safe 'integerp)
-
-(defcustom org-deadline-past-days 10000
- "Number of days to warn about missed deadlines.
-When an item has deadline on a date, it shows up in the agenda on
-this day and will appear as a reminder until it is marked DONE or
-for the number of days given here."
- :group 'org-agenda-daily/weekly
- :type 'integer
- :version "26.1"
- :package-version '(Org . "9.1")
- :safe 'integerp)
-
-(defcustom org-agenda-log-mode-items '(closed clock)
- "List of items that should be shown in agenda log mode.
-\\<org-agenda-mode-map>\
-This list may contain the following symbols:
-
- closed Show entries that have been closed on that day.
- clock Show entries that have received clocked time on that day.
- state Show all logged state changes.
-Note that instead of changing this variable, you can also press \
-`\\[universal-argument] \\[org-agenda-log-mode]' in
-the agenda to display all available LOG items temporarily."
- :group 'org-agenda-daily/weekly
- :type '(set :greedy t (const closed) (const clock) (const state)))
-
-(defcustom org-agenda-clock-consistency-checks
- '(:max-duration "10:00" :min-duration 0 :max-gap "0:05"
- :gap-ok-around ("4:00")
- :default-face ((:background "DarkRed") (:foreground "white"))
- :overlap-face nil :gap-face nil :no-end-time-face nil
- :long-face nil :short-face nil)
- "This is a property list, with the following keys:
-
-:max-duration Mark clocking chunks that are longer than this time.
- This is a time string like \"HH:MM\", or the number
- of minutes as an integer.
-
-:min-duration Mark clocking chunks that are shorter that this.
- This is a time string like \"HH:MM\", or the number
- of minutes as an integer.
-
-:max-gap Mark gaps between clocking chunks that are longer than
- this duration. A number of minutes, or a string
- like \"HH:MM\".
-
-:gap-ok-around List of times during the day which are usually not working
- times. When a gap is detected, but the gap contains any
- of these times, the gap is *not* reported. For example,
- if this is (\"4:00\" \"13:00\") then gaps that contain
- 4:00 in the morning (i.e. the night) and 13:00
- (i.e. a typical lunch time) do not cause a warning.
- You should have at least one time during the night in this
- list, or otherwise the first task each morning will trigger
- a warning because it follows a long gap.
-
-Furthermore, the following properties can be used to define faces for
-issue display.
-
-:default-face the default face, if the specific face is undefined
-:overlap-face face for overlapping clocks
-:gap-face face for gaps between clocks
-:no-end-time-face face for incomplete clocks
-:long-face face for clock intervals that are too long
-:short-face face for clock intervals that are too short"
- :group 'org-agenda-daily/weekly
- :group 'org-clock
- :version "24.1"
- :type 'plist)
-
-(defcustom org-agenda-log-mode-add-notes t
- "Non-nil means add first line of notes to log entries in agenda views.
-If a log item like a state change or a clock entry is associated with
-notes, the first line of these notes will be added to the entry in the
-agenda display."
- :group 'org-agenda-daily/weekly
- :type 'boolean)
-
-(defcustom org-agenda-start-with-log-mode nil
- "The initial value of log-mode in a newly created agenda window.
-See `org-agenda-log-mode' and `org-agenda-log-mode-items' for further
-explanations on the possible values."
- :group 'org-agenda-startup
- :group 'org-agenda-daily/weekly
- :type '(choice (const :tag "Don't show log items" nil)
- (const :tag "Show only log items" only)
- (const :tag "Show all possible log items" clockcheck)
- (repeat :tag "Choose among possible values for `org-agenda-log-mode-items'"
- (choice (const :tag "Show closed log items" closed)
- (const :tag "Show clocked log items" clock)
- (const :tag "Show all logged state changes" state)))))
-
-(defcustom org-agenda-start-with-clockreport-mode nil
- "The initial value of clockreport-mode in a newly created agenda window."
- :group 'org-agenda-startup
- :group 'org-agenda-daily/weekly
- :type 'boolean)
-
-(defcustom org-agenda-clockreport-parameter-plist '(:link t :maxlevel 2)
- "Property list with parameters for the clocktable in clockreport mode.
-This is the display mode that shows a clock table in the daily/weekly
-agenda, the properties for this dynamic block can be set here.
-The usual clocktable parameters are allowed here, but you cannot set
-the properties :name, :tstart, :tend, :block, and :scope - these will
-be overwritten to make sure the content accurately reflects the
-current display in the agenda."
- :group 'org-agenda-daily/weekly
- :type 'plist)
-
-(defvaralias 'org-agenda-search-view-search-words-only
- 'org-agenda-search-view-always-boolean)
-
-(defcustom org-agenda-search-view-always-boolean nil
- "Non-nil means the search string is interpreted as individual parts.
-
-The search string for search view can either be interpreted as a phrase,
-or as a list of snippets that define a boolean search for a number of
-strings.
-
-When this is non-nil, the string will be split on whitespace, and each
-snippet will be searched individually, and all must match in order to
-select an entry. A snippet is then a single string of non-white
-characters, or a string in double quotes, or a regexp in {} braces.
-If a snippet is preceded by \"-\", the snippet must *not* match.
-\"+\" is syntactic sugar for positive selection. Each snippet may
-be found as a full word or a partial word, but see the variable
-`org-agenda-search-view-force-full-words'.
-
-When this is nil, search will look for the entire search phrase as one,
-with each space character matching any amount of whitespace, including
-line breaks.
-
-Even when this is nil, you can still switch to Boolean search dynamically
-by preceding the first snippet with \"+\" or \"-\". If the first snippet
-is a regexp marked with braces like \"{abc}\", this will also switch to
-boolean search."
- :group 'org-agenda-search-view
- :version "24.1"
- :type 'boolean)
-
-(defcustom org-agenda-search-view-force-full-words nil
- "Non-nil means, search words must be matches as complete words.
-When nil, they may also match part of a word."
- :group 'org-agenda-search-view
- :version "24.1"
- :type 'boolean)
-
-(defcustom org-agenda-search-view-max-outline-level 0
- "Maximum outline level to display in search view.
-E.g. when this is set to 1, the search view will only
-show headlines of level 1. When set to 0, the default
-value, don't limit agenda view by outline level."
- :group 'org-agenda-search-view
- :version "26.1"
- :package-version '(Org . "8.3")
- :type 'integer)
-
-(defgroup org-agenda-time-grid nil
- "Options concerning the time grid in the Org Agenda."
- :tag "Org Agenda Time Grid"
- :group 'org-agenda)
-
-(defcustom org-agenda-search-headline-for-time t
- "Non-nil means search headline for a time-of-day.
-If the headline contains a time-of-day in one format or another, it will
-be used to sort the entry into the time sequence of items for a day.
-Some people have time stamps in the headline that refer to the creation
-time or so, and then this produces an unwanted side effect. If this is
-the case for your, use this variable to turn off searching the headline
-for a time."
- :group 'org-agenda-time-grid
- :type 'boolean)
-
-(defcustom org-agenda-use-time-grid t
- "Non-nil means show a time grid in the agenda schedule.
-A time grid is a set of lines for specific times (like every two hours between
-8:00 and 20:00). The items scheduled for a day at specific times are
-sorted in between these lines.
-For details about when the grid will be shown, and what it will look like, see
-the variable `org-agenda-time-grid'."
- :group 'org-agenda-time-grid
- :type 'boolean)
-
-(defcustom org-agenda-time-grid
- '((daily today require-timed)
- (800 1000 1200 1400 1600 1800 2000)
- "......"
- "----------------")
-
- "The settings for time grid for agenda display.
-This is a list of four items. The first item is again a list. It contains
-symbols specifying conditions when the grid should be displayed:
-
- daily if the agenda shows a single day
- 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 list of integers, indicating the times that
-should have a grid line.
-
-The third item is a string which will be placed right after the
-times that have a grid line.
-
-The fourth item is a string placed after the grid times. This
-will align with agenda items."
- :group 'org-agenda-time-grid
- :type
- '(list
- (set :greedy t :tag "Grid Display Options"
- (const :tag "Show grid in single day agenda display" daily)
- (const :tag "Show grid in weekly agenda display" weekly)
- (const :tag "Always show grid for today" today)
- (const :tag "Show grid only if any timed entries are present"
- require-timed)
- (const :tag "Skip grid times already present in an entry"
- remove-match))
- (repeat :tag "Grid Times" (integer :tag "Time"))
- (string :tag "Grid String (after agenda times)")
- (string :tag "Grid String (aligns with agenda items)")))
-
-(defcustom org-agenda-show-current-time-in-grid t
- "Non-nil means show the current time in the time grid."
- :group 'org-agenda-time-grid
- :version "24.1"
- :type 'boolean)
-
-(defcustom org-agenda-current-time-string
- "now - - - - - - - - - - - - - - - - - - - - - - - - -"
- "The string for the current time marker in the agenda."
- :group 'org-agenda-time-grid
- :version "24.1"
- :type 'string)
-
-(defgroup org-agenda-sorting nil
- "Options concerning sorting in the Org Agenda."
- :tag "Org Agenda Sorting"
- :group 'org-agenda)
-
-(defcustom org-agenda-sorting-strategy
- '((agenda habit-down time-up priority-down category-keep)
- (todo priority-down category-keep)
- (tags priority-down category-keep)
- (search category-keep))
- "Sorting structure for the agenda items of a single day.
-This is a list of symbols which will be used in sequence to determine
-if an entry should be listed before another entry. The following
-symbols are recognized:
-
-time-up Put entries with time-of-day indications first, early first.
-time-down Put entries with time-of-day indications first, late first.
-timestamp-up Sort by any timestamp, early first.
-timestamp-down Sort by any timestamp, late first.
-scheduled-up Sort by scheduled timestamp, early first.
-scheduled-down Sort by scheduled timestamp, late first.
-deadline-up Sort by deadline timestamp, early first.
-deadline-down Sort by deadline timestamp, late first.
-ts-up Sort by active timestamp, early first.
-ts-down Sort by active timestamp, late first.
-tsia-up Sort by inactive timestamp, early first.
-tsia-down Sort by inactive timestamp, late first.
-category-keep Keep the default order of categories, corresponding to the
- sequence in `org-agenda-files'.
-category-up Sort alphabetically by category, A-Z.
-category-down Sort alphabetically by category, Z-A.
-tag-up Sort alphabetically by last tag, A-Z.
-tag-down Sort alphabetically by last tag, Z-A.
-priority-up Sort numerically by priority, high priority last.
-priority-down Sort numerically by priority, high priority first.
-todo-state-up Sort by todo state, tasks that are done last.
-todo-state-down Sort by todo state, tasks that are done first.
-effort-up Sort numerically by estimated effort, high effort last.
-effort-down Sort numerically by estimated effort, high effort first.
-user-defined-up Sort according to `org-agenda-cmp-user-defined', high last.
-user-defined-down Sort according to `org-agenda-cmp-user-defined', high first.
-habit-up Put entries that are habits first.
-habit-down Put entries that are habits last.
-alpha-up Sort headlines alphabetically.
-alpha-down Sort headlines alphabetically, reversed.
-
-The different possibilities will be tried in sequence, and testing stops
-if one comparison returns a \"not-equal\". For example, the default
- '(time-up category-keep priority-down)
-means: Pull out all entries having a specified time of day and sort them,
-in order to make a time schedule for the current day the first thing in the
-agenda listing for the day. Of the entries without a time indication, keep
-the grouped in categories, don't sort the categories, but keep them in
-the sequence given in `org-agenda-files'. Within each category sort by
-priority.
-
-Leaving out `category-keep' would mean that items will be sorted across
-categories by priority.
-
-Instead of a single list, this can also be a set of list for specific
-contents, with a context symbol in the car of the list, any of
-`agenda', `todo', `tags', `search' for the corresponding agenda views.
-
-Custom commands can bind this variable in the options section."
- :group 'org-agenda-sorting
- :type `(choice
- (repeat :tag "General" ,org-sorting-choice)
- (list :tag "Individually"
- (cons (const :tag "Strategy for Weekly/Daily agenda" agenda)
- (repeat ,org-sorting-choice))
- (cons (const :tag "Strategy for TODO lists" todo)
- (repeat ,org-sorting-choice))
- (cons (const :tag "Strategy for Tags matches" tags)
- (repeat ,org-sorting-choice))
- (cons (const :tag "Strategy for search matches" search)
- (repeat ,org-sorting-choice)))))
-
-(defcustom org-agenda-cmp-user-defined nil
- "A function to define the comparison `user-defined'.
-This function must receive two arguments, agenda entry a and b.
-If a>b, return +1. If a<b, return -1. If they are equal as seen by
-the user comparison, return nil.
-When this is defined, you can make `user-defined-up' and `user-defined-down'
-part of an agenda sorting strategy."
- :group 'org-agenda-sorting
- :type 'symbol)
-
-(defcustom org-agenda-sort-notime-is-late t
- "Non-nil means items without time are considered late.
-This is only relevant for sorting. When t, items which have no explicit
-time like 15:30 will be considered as 99:01, i.e. later than any items which
-do have a time. When nil, the default time is before 0:00. You can use this
-option to decide if the schedule for today should come before or after timeless
-agenda entries."
- :group 'org-agenda-sorting
- :type 'boolean)
-
-(defcustom org-agenda-sort-noeffort-is-high t
- "Non-nil means items without effort estimate are sorted as high effort.
-This also applies when filtering an agenda view with respect to the
-< or > effort operator. Then, tasks with no effort defined will be treated
-as tasks with high effort.
-When nil, such items are sorted as 0 minutes effort."
- :group 'org-agenda-sorting
- :type 'boolean)
-
-(defgroup org-agenda-line-format nil
- "Options concerning the entry prefix in the Org agenda display."
- :tag "Org Agenda Line Format"
- :group 'org-agenda)
-
-(defcustom org-agenda-prefix-format
- '((agenda . " %i %-12:c%?-12t% s")
- (todo . " %i %-12:c")
- (tags . " %i %-12:c")
- (search . " %i %-12:c"))
- "Format specifications for the prefix of items in the agenda views.
-
-An alist with one entry per agenda type. The keys of the
-sublists are `agenda', `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
- %e the effort required by the item
- %l the level of the item (insert X space(s) if item is of level X)
- %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
- %b show breadcrumbs, i.e., the names of the higher levels
- %(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.
-
-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.
-
-If there is punctuation or whitespace character just before the
-final format letter, this character will be appended to the field
-value if the value is not empty. For example, the format
-\"%-12:c\" leads to \"Diary: \" if the category is \"Diary\". If
-the category is empty, no additional colon is inserted.
-
-The default value for the agenda sublist is \" %-12:c%?-12t% s\",
-which means:
-
-- Indent the line with two space characters
-- 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.
-
-See also the variables `org-agenda-remove-times-when-in-prefix' and
-`org-agenda-remove-tags'.
-
-Custom commands can set this variable in the options section."
- :type '(choice
- (string :tag "General format")
- (list :greedy t :tag "View dependent"
- (cons (const agenda) (string :tag "Format"))
- (cons (const todo) (string :tag "Format"))
- (cons (const tags) (string :tag "Format"))
- (cons (const search) (string :tag "Format"))))
- :group 'org-agenda-line-format
- :version "26.1"
- :package-version '(Org . "9.1"))
-
-(defcustom org-agenda-breadcrumbs-separator "->"
- "The separator of breadcrumbs in agenda lines."
- :group 'org-agenda-line-format
- :package-version '(Org . "9.3")
- :type 'string
- :safe #'stringp)
-
-(defvar org-prefix-format-compiled nil
- "The compiled prefix format and associated variables.
-This is a list where first element is a list of variable bindings, and second
-element is the compiled format expression. See the variable
-`org-agenda-prefix-format'.")
-
-(defcustom org-agenda-todo-keyword-format "%-1s"
- "Format for the TODO keyword in agenda lines.
-Set this to something like \"%-12s\" if you want all TODO keywords
-to occupy a fixed space in the agenda display."
- :group 'org-agenda-line-format
- :type 'string)
-
-(defcustom org-agenda-diary-sexp-prefix nil
- "A regexp that matches part of a diary sexp entry
-which should be treated as scheduling/deadline information in
-`org-agenda'.
-
-For example, you can use this to extract the `diary-remind-message' from
-`diary-remind' entries."
- :group 'org-agenda-line-format
- :type '(choice (const :tag "None" nil) (regexp :tag "Regexp")))
-
-(defcustom org-agenda-timerange-leaders '("" "(%d/%d): ")
- "Text preceding timerange entries in the agenda view.
-This is a list with two strings. The first applies when the range
-is entirely on one day. The second applies if the range spans several days.
-The strings may have two \"%d\" format specifiers which will be filled
-with the sequence number of the days, and the total number of days in the
-range, respectively."
- :group 'org-agenda-line-format
- :type '(list
- (string :tag "Deadline today ")
- (choice :tag "Deadline relative"
- (string :tag "Format string")
- (function))))
-
-(defcustom org-agenda-scheduled-leaders '("Scheduled: " "Sched.%2dx: ")
- "Text preceding scheduled items in the agenda view.
-This is a list with two strings. The first applies when the item is
-scheduled on the current day. The second applies when it has been scheduled
-previously, it may contain a %d indicating that this is the nth time that
-this item is scheduled, due to automatic rescheduling of unfinished items
-for the following day. So this number is one larger than the number of days
-that passed since this item was scheduled first."
- :group 'org-agenda-line-format
- :version "24.4"
- :package-version '(Org . "8.0")
- :type '(list
- (string :tag "Scheduled today ")
- (string :tag "Scheduled previously")))
-
-(defcustom org-agenda-inactive-leader "["
- "Text preceding item pulled into the agenda by inactive time stamps.
-These entries are added to the agenda when pressing \"[\"."
- :group 'org-agenda-line-format
- :version "24.1"
- :type 'string)
-
-(defcustom org-agenda-deadline-leaders '("Deadline: " "In %3d d.: " "%2d d. ago: ")
- "Text preceding deadline items in the agenda view.
-This is a list with three strings. The first applies when the item has its
-deadline on the current day. The second applies when the deadline is in the
-future, the third one when it is in the past. The strings may contain %d
-to capture the number of days."
- :group 'org-agenda-line-format
- :version "24.4"
- :package-version '(Org . "8.0")
- :type '(list
- (string :tag "Deadline today ")
- (string :tag "Deadline in the future ")
- (string :tag "Deadline in the past ")))
-
-(defcustom org-agenda-remove-times-when-in-prefix t
- "Non-nil means remove duplicate time specifications in agenda items.
-When the format `org-agenda-prefix-format' contains a `%t' specifier, a
-time-of-day specification in a headline or diary entry is extracted and
-placed into the prefix. If this option is non-nil, the original specification
-\(a timestamp or -range, or just a plain time(range) specification like
-11:30-4pm) will be removed for agenda display. This makes the agenda less
-cluttered.
-The option can be t or nil. It may also be the symbol `beg', indicating
-that the time should only be removed when it is located at the beginning of
-the headline/diary entry."
- :group 'org-agenda-line-format
- :type '(choice
- (const :tag "Always" t)
- (const :tag "Never" nil)
- (const :tag "When at beginning of entry" beg)))
-
-(defcustom org-agenda-remove-timeranges-from-blocks nil
- "Non-nil means remove time ranges specifications in agenda
-items that span on several days."
- :group 'org-agenda-line-format
- :version "24.1"
- :type 'boolean)
-
-(defcustom org-agenda-default-appointment-duration nil
- "Default duration for appointments that only have a starting time.
-When nil, no duration is specified in such cases.
-When non-nil, this must be the number of minutes, e.g. 60 for one hour."
- :group 'org-agenda-line-format
- :type '(choice
- (integer :tag "Minutes")
- (const :tag "No default duration")))
-
-(defcustom org-agenda-show-inherited-tags t
- "Non-nil means show inherited tags in each agenda line.
-
-When this option is set to `always', it takes precedence over
-`org-agenda-use-tag-inheritance' and inherited tags are shown
-in every agenda.
-
-When this option is set to t (the default), inherited tags are
-shown when they are available, i.e. when the value of
-`org-agenda-use-tag-inheritance' enables tag inheritance for the
-given agenda type.
-
-This can be set to a list of agenda types in which the agenda
-must display the inherited tags. Available types are `todo',
-`agenda' and `search'.
-
-When set to nil, never show inherited tags in agenda lines."
- :group 'org-agenda-line-format
- :group 'org-agenda
- :version "24.3"
- :type '(choice
- (const :tag "Show inherited tags when available" t)
- (const :tag "Always show inherited tags" always)
- (repeat :tag "Show inherited tags only in selected agenda types"
- (symbol :tag "Agenda type"))))
-
-(defcustom org-agenda-use-tag-inheritance '(todo search agenda)
- "List of agenda view types where to use tag inheritance.
-
-In tags/tags-todo/tags-tree agenda views, tag inheritance is
-controlled by `org-use-tag-inheritance'. In other agenda types,
-`org-use-tag-inheritance' is not used for the selection of the
-agenda entries. Still, you may want the agenda to be aware of
-the inherited tags anyway, e.g. for later tag filtering.
-
-Allowed value are `todo', `search' and `agenda'.
-
-This variable has no effect if `org-agenda-show-inherited-tags'
-is set to `always'. In that case, the agenda is aware of those
-tags.
-
-The default value sets tags in every agenda type. Setting this
-option to nil will speed up non-tags agenda view a lot."
- :group 'org-agenda
- :version "26.1"
- :package-version '(Org . "9.1")
- :type '(choice
- (const :tag "Use tag inheritance in all agenda types" t)
- (repeat :tag "Use tag inheritance in selected agenda types"
- (symbol :tag "Agenda type"))))
-
-(defcustom org-agenda-hide-tags-regexp nil
- "Regular expression used to filter away specific tags in agenda views.
-This means that these tags will be present, but not be shown in the agenda
-line. Secondary filtering will still work on the hidden tags.
-Nil means don't hide any tags."
- :group 'org-agenda-line-format
- :type '(choice
- (const :tag "Hide none" nil)
- (regexp :tag "Regexp ")))
-
-(defvaralias 'org-agenda-remove-tags-when-in-prefix
- 'org-agenda-remove-tags)
-
-(defcustom org-agenda-remove-tags nil
- "Non-nil means remove the tags from the headline copy in the agenda.
-When this is the symbol `prefix', only remove tags when
-`org-agenda-prefix-format' contains a `%T' specifier."
- :group 'org-agenda-line-format
- :type '(choice
- (const :tag "Always" t)
- (const :tag "Never" nil)
- (const :tag "When prefix format contains %T" prefix)))
-
-(defvaralias 'org-agenda-align-tags-to-column 'org-agenda-tags-column)
-
-(defcustom org-agenda-tags-column 'auto
- "Shift tags in agenda items to this column.
-If set to `auto', tags will be automatically aligned to the right
-edge of the window.
-
-If set to a positive number, tags will be left-aligned to that
-column. If set to a negative number, tags will be right-aligned
-to that column. For example, -80 works well for a normal 80
-character screen."
- :group 'org-agenda-line-format
- :type '(choice
- (const :tag "Automatically align to right edge of window" auto)
- (integer :tag "Specific column" -80))
- :package-version '(Org . "9.1")
- :version "26.1")
-
-(defcustom org-agenda-fontify-priorities 'cookies
- "Non-nil means highlight low and high priorities in agenda.
-When t, the highest priority entries are bold, lowest priority italic.
-However, settings in `org-priority-faces' will overrule these faces.
-When this variable is the symbol `cookies', only fontify the
-cookies, not the entire task.
-This may also be an association list of priority faces, whose
-keys are the character values of `org-priority-highest',
-`org-priority-default', and `org-priority-lowest' (the default values
-are ?A, ?B, and ?C, respectively). The face may be a named face, a
-color as a string, or a list like `(:background \"Red\")'.
-If it is a color, the variable `org-faces-easy-properties'
-determines if it is a foreground or a background color."
- :group 'org-agenda-line-format
- :type '(choice
- (const :tag "Never" nil)
- (const :tag "Defaults" t)
- (const :tag "Cookies only" cookies)
- (repeat :tag "Specify"
- (list (character :tag "Priority" :value ?A)
- (choice :tag "Face "
- (string :tag "Color")
- (sexp :tag "Face"))))))
-
-(defcustom org-agenda-day-face-function nil
- "Function called to determine what face should be used to display a day.
-The only argument passed to that function is the day. It should
-returns a face, or nil if does not want to specify a face and let
-the normal rules apply."
- :group 'org-agenda-line-format
- :version "24.1"
- :type '(choice (const nil) (function)))
-
-(defcustom org-agenda-category-icon-alist nil
- "Alist of category icon to be displayed in agenda views.
-
-Each entry should have the following format:
-
- (CATEGORY-REGEXP FILE-OR-DATA TYPE DATA-P PROPS)
-
-Where CATEGORY-REGEXP is a regexp matching the categories where
-the icon should be displayed.
-FILE-OR-DATA either a file path or a string containing image data.
-
-The other fields can be omitted safely if not needed:
-TYPE indicates the image type.
-DATA-P is a boolean indicating whether the FILE-OR-DATA string is
-image data.
-PROPS are additional image attributes to assign to the image,
-like, e.g. `:ascent center'.
-
- (\"Org\" \"/path/to/icon.png\" nil nil :ascent center)
-
-If you want to set the display properties yourself, just put a
-list as second element:
-
- (CATEGORY-REGEXP (MY PROPERTY LIST))
-
-For example, to display a 16px horizontal space for Emacs
-category, you can use:
-
- (\"Emacs\" \\='(space . (:width (16))))"
- :group 'org-agenda-line-format
- :version "24.1"
- :type '(alist :key-type (regexp :tag "Regexp matching category")
- :value-type (choice (list :tag "Icon"
- (string :tag "File or data")
- (symbol :tag "Type")
- (boolean :tag "Data?")
- (repeat :tag "Extra image properties" :inline t sexp))
- (list :tag "Display properties" sexp))))
-
-(defgroup org-agenda-column-view nil
- "Options concerning column view in the agenda."
- :tag "Org Agenda Column View"
- :group 'org-agenda)
-
-(defcustom org-agenda-view-columns-initially nil
- "When non-nil, switch to columns view right after creating the agenda."
- :group 'org-agenda-column-view
- :type 'boolean
- :version "26.1"
- :package-version '(Org . "9.0")
- :safe #'booleanp)
-
-(defcustom org-agenda-columns-show-summaries t
- "Non-nil means show summaries for columns displayed in the agenda view."
- :group 'org-agenda-column-view
- :type 'boolean)
-
-(defcustom org-agenda-columns-compute-summary-properties t
- "Non-nil means recompute all summary properties before column view.
-When column view in the agenda is listing properties that have a summary
-operator, it can go to all relevant buffers and recompute the summaries
-there. This can mean overhead for the agenda column view, but is necessary
-to have thing up to date.
-As a special case, a CLOCKSUM property also makes sure that the clock
-computations are current."
- :group 'org-agenda-column-view
- :type 'boolean)
-
-(defcustom org-agenda-columns-add-appointments-to-effort-sum nil
- "Non-nil means the duration of an appointment will add to day effort.
-The property to which appointment durations will be added is the one given
-in the option `org-effort-property'. If an appointment does not have
-an end time, `org-agenda-default-appointment-duration' will be used. If that
-is not set, an appointment without end time will not contribute to the time
-estimate."
- :group 'org-agenda-column-view
- :type 'boolean)
-
-(defcustom org-agenda-auto-exclude-function nil
- "A function called with a tag to decide if it is filtered on \
-\\<org-agenda-mode-map>`\\[org-agenda-filter-by-tag] 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
-as normal, \"-<TAG>\" to exclude the tag, or \"+<TAG>\" to exclude
-lines not carrying this tag.
-Note that for the purpose of tag filtering, only the lower-case version of
-all tags will be considered, so that this function will only ever see
-the lower-case version of all tags."
- :group 'org-agenda
- :type '(choice (const nil) (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.
-
-You can also specify a function which collects arguments to be
-used for each call to your bulk custom function. The argument
-collecting function will be run once and should return a list of
-arguments to pass to the bulk function. For example:
-
- \\='((?R set-category get-category))
-
-Now, `B R' will call the custom `get-category' which would prompt
-the user once for a category. That category is then passed as an
-argument to `set-category' for each entry it's called against."
- :type
- '(alist :key-type character
- :value-type
- (group (function :tag "Bulk Custom Function")
- (choice (function :tag "Bulk Custom Argument Function")
- (const :tag "No Bulk Custom Argument Function" nil))))
- :package-version '(Org . "9.5")
- :group 'org-agenda)
-
-(defmacro org-agenda-with-point-at-orig-entry (string &rest body)
- "Execute BODY with point at location given by `org-hd-marker' property.
-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."
- (declare (debug t))
- (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)))))
-
-(defun org-add-agenda-custom-command (entry)
- "Replace or add a command in `org-agenda-custom-commands'.
-This is mostly for hacking and trying a new command - once the command
-works you probably want to add it to `org-agenda-custom-commands' for good."
- (let ((ass (assoc (car entry) org-agenda-custom-commands)))
- (if ass
- (setcdr ass (cdr entry))
- (push entry org-agenda-custom-commands))))
-
-(defmacro org-agenda--insert-overriding-header (default)
- "Insert header into agenda view.
-The inserted header depends on `org-agenda-overriding-header'.
-If the empty string, don't insert a header. If any other string,
-insert it as a header. If nil, insert DEFAULT, which should
-evaluate to a string. If a function, call it and insert the
-string that it returns."
- (declare (debug (form)) (indent defun))
- `(cond
- ((not org-agenda-overriding-header) (insert ,default))
- ((equal org-agenda-overriding-header "") nil)
- ((stringp org-agenda-overriding-header)
- (insert (propertize org-agenda-overriding-header
- 'face 'org-agenda-structure)
- "\n"))
- ((functionp org-agenda-overriding-header)
- (insert (funcall org-agenda-overriding-header)))
- (t (user-error "Invalid value for `org-agenda-overriding-header': %S"
- org-agenda-overriding-header))))
-
-;;; Define the org-agenda-mode
-
-(defvaralias 'org-agenda-keymap 'org-agenda-mode-map)
-(defvar org-agenda-mode-map (make-sparse-keymap)
- "Keymap for `org-agenda-mode'.")
-
-(org-remap org-agenda-mode-map 'move-end-of-line 'org-agenda-end-of-line)
-
-(defvar org-agenda-menu) ; defined later in this file.
-(defvar org-agenda-restrict nil) ; defined later in this file.
-(defvar org-agenda-follow-mode nil)
-(defvar org-agenda-entry-text-mode nil)
-(defvar org-agenda-clockreport-mode nil)
-(defvar org-agenda-show-log nil
- "When non-nil, show the log in the agenda.
-Do not set this directly; instead use
-`org-agenda-start-with-log-mode', which see.")
-(defvar org-agenda-redo-command nil)
-(defvar org-agenda-query-string nil)
-(defvar org-agenda-mode-hook nil
- "Hook run after `org-agenda-mode' is turned on.
-The buffer is still writable when this hook is called.")
-(defvar org-agenda-type nil)
-(defvar org-agenda-force-single-file nil)
-(defvar org-agenda-bulk-marked-entries nil
- "List of markers that refer to marked entries in the agenda.")
-(defvar org-agenda-current-date nil
- "Active date when building the agenda.")
-
-;;; Multiple agenda buffers support
-
-(defcustom org-agenda-sticky nil
- "Non-nil means agenda q key will bury agenda buffers.
-Agenda commands will then show existing buffer instead of generating new ones.
-When nil, `q' will kill the single agenda buffer."
- :group 'org-agenda
- :version "24.3"
- :type 'boolean)
-
-
-;;;###autoload
-(defun org-toggle-sticky-agenda (&optional arg)
- "Toggle `org-agenda-sticky'."
- (interactive "P")
- (let ((new-value (if arg
- (> (prefix-numeric-value arg) 0)
- (not org-agenda-sticky))))
- (if (equal new-value org-agenda-sticky)
- (and (called-interactively-p 'interactive)
- (message "Sticky agenda was already %s"
- (if org-agenda-sticky "enabled" "disabled")))
- (setq org-agenda-sticky new-value)
- (org-agenda-kill-all-agenda-buffers)
- (and (called-interactively-p 'interactive)
- (message "Sticky agenda %s"
- (if org-agenda-sticky "enabled" "disabled"))))))
-
-(defvar org-agenda-buffer nil
- "Agenda buffer currently being generated.")
-
-(defvar org-agenda-last-prefix-arg nil)
-(defvar org-agenda-this-buffer-name nil)
-(defvar org-agenda-doing-sticky-redo nil)
-(defvar org-agenda-this-buffer-is-sticky nil)
-(defvar org-agenda-last-indirect-buffer nil
- "Last buffer loaded by `org-agenda-tree-to-indirect-buffer'.")
-
-(defconst org-agenda-local-vars
- '(org-agenda-this-buffer-name
- org-agenda-undo-list
- org-agenda-pending-undo-list
- org-agenda-follow-mode
- org-agenda-entry-text-mode
- org-agenda-clockreport-mode
- org-agenda-show-log
- org-agenda-redo-command
- org-agenda-query-string
- org-agenda-type
- org-agenda-bulk-marked-entries
- org-agenda-undo-has-started-in
- org-agenda-info
- org-agenda-pre-window-conf
- org-agenda-columns-active
- org-agenda-tag-filter
- org-agenda-category-filter
- org-agenda-top-headline-filter
- org-agenda-regexp-filter
- org-agenda-effort-filter
- org-agenda-markers
- org-agenda-last-search-view-search-was-boolean
- org-agenda-last-indirect-buffer
- org-agenda-filtered-by-category
- org-agenda-filter-form
- org-agenda-cycle-counter
- org-agenda-last-prefix-arg)
- "Variables that must be local in agenda buffers to allow multiple buffers.")
-
-(defun org-agenda-mode ()
- "Mode for time-sorted view on action items in Org files.
-
-The following commands are available:
-
-\\{org-agenda-mode-map}"
- (interactive)
- (ignore-errors (require 'face-remap))
- (let ((agenda-local-vars-to-keep
- '(text-scale-mode-amount
- text-scale-mode
- text-scale-mode-lighter
- face-remapping-alist))
- (save (buffer-local-variables)))
- (kill-all-local-variables)
- (cl-flet ((reset-saved (var-set)
- "Reset variables in VAR-SET to possibly stored value in SAVE."
- (dolist (elem save)
- (pcase elem
- (`(,var . ,val) ;ignore unbound variables
- (when (and val (memq var var-set))
- (set var val)))))))
- (cond (org-agenda-doing-sticky-redo
- ;; Refreshing sticky agenda-buffer
- ;;
- ;; Preserve the value of `org-agenda-local-vars' variables.
- (mapc #'make-local-variable org-agenda-local-vars)
- (reset-saved org-agenda-local-vars)
- (setq-local org-agenda-this-buffer-is-sticky t))
- (org-agenda-sticky
- ;; Creating a sticky Agenda buffer for the first time
- (mapc #'make-local-variable org-agenda-local-vars)
- (setq-local org-agenda-this-buffer-is-sticky t))
- (t
- ;; Creating a non-sticky agenda buffer
- (setq-local org-agenda-this-buffer-is-sticky nil)))
- (mapc #'make-local-variable agenda-local-vars-to-keep)
- (reset-saved agenda-local-vars-to-keep)))
- (setq org-agenda-undo-list nil
- org-agenda-pending-undo-list nil
- org-agenda-bulk-marked-entries nil)
- (setq major-mode 'org-agenda-mode)
- ;; Keep global-font-lock-mode from turning on font-lock-mode
- (setq-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)
- (when org-startup-truncated (setq truncate-lines t))
- (setq-local line-move-visual nil)
- (add-hook 'post-command-hook #'org-agenda-update-agenda-type nil 'local)
- (add-hook 'pre-command-hook #'org-unhighlight nil 'local)
- ;; Make sure properties are removed when copying text
- (if (boundp 'filter-buffer-substring-functions)
- (add-hook 'filter-buffer-substring-functions
- (lambda (fun start end delete)
- (substring-no-properties (funcall fun start end delete)))
- nil t)
- ;; Emacs >= 24.4.
- (add-function :filter-return (local 'filter-buffer-substring-function)
- #'substring-no-properties))
- (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-show-log org-agenda-start-with-log-mode
- 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
- (list
- (vector
- (if (get 'org-agenda-files 'org-restrict)
- "Restricted to single file"
- "Edit File List")
- '(org-edit-agenda-file-list)
- (not (get 'org-agenda-files 'org-restrict)))
- "--")
- (mapcar #'org-file-menu-entry (org-agenda-files))))
- (org-agenda-set-mode-name)
- (run-mode-hooks 'org-agenda-mode-hook))
-
-(substitute-key-definition #'undo #'org-agenda-undo
- org-agenda-mode-map global-map)
-(org-defkey org-agenda-mode-map "\C-i" #'org-agenda-goto)
-(org-defkey org-agenda-mode-map [(tab)] #'org-agenda-goto)
-(org-defkey org-agenda-mode-map "\C-m" #'org-agenda-switch-to)
-(org-defkey org-agenda-mode-map "\C-k" #'org-agenda-kill)
-(org-defkey org-agenda-mode-map "\C-c\C-w" #'org-agenda-refile)
-(org-defkey org-agenda-mode-map [(meta down)] #'org-agenda-drag-line-forward)
-(org-defkey org-agenda-mode-map [(meta up)] #'org-agenda-drag-line-backward)
-(org-defkey org-agenda-mode-map "m" #'org-agenda-bulk-mark)
-(org-defkey org-agenda-mode-map "\M-m" #'org-agenda-bulk-toggle)
-(org-defkey org-agenda-mode-map "*" #'org-agenda-bulk-mark-all)
-(org-defkey org-agenda-mode-map "\M-*" #'org-agenda-bulk-toggle-all)
-(org-defkey org-agenda-mode-map "#" #'org-agenda-dim-blocked-tasks)
-(org-defkey org-agenda-mode-map "%" #'org-agenda-bulk-mark-regexp)
-(org-defkey org-agenda-mode-map "u" #'org-agenda-bulk-unmark)
-(org-defkey org-agenda-mode-map "U" #'org-agenda-bulk-unmark-all)
-(org-defkey org-agenda-mode-map "B" #'org-agenda-bulk-action)
-(org-defkey org-agenda-mode-map "k" #'org-agenda-capture)
-(org-defkey org-agenda-mode-map "A" #'org-agenda-append-agenda)
-(org-defkey org-agenda-mode-map "\C-c\C-x!" #'org-reload)
-(org-defkey org-agenda-mode-map "\C-c\C-x\C-a" #'org-agenda-archive-default)
-(org-defkey org-agenda-mode-map "\C-c\C-xa" #'org-agenda-toggle-archive-tag)
-(org-defkey org-agenda-mode-map "\C-c\C-xA" #'org-agenda-archive-to-archive-sibling)
-(org-defkey org-agenda-mode-map "\C-c\C-x\C-s" #'org-agenda-archive)
-(org-defkey org-agenda-mode-map "\C-c$" #'org-agenda-archive)
-(org-defkey org-agenda-mode-map "$" #'org-agenda-archive)
-(org-defkey org-agenda-mode-map "\C-c\C-o" #'org-agenda-open-link)
-(org-defkey org-agenda-mode-map " " #'org-agenda-show-and-scroll-up)
-(org-defkey org-agenda-mode-map [backspace] #'org-agenda-show-scroll-down)
-(org-defkey org-agenda-mode-map "\d" #'org-agenda-show-scroll-down)
-(org-defkey org-agenda-mode-map [(control shift right)] #'org-agenda-todo-nextset)
-(org-defkey org-agenda-mode-map [(control shift left)] #'org-agenda-todo-previousset)
-(org-defkey org-agenda-mode-map "\C-c\C-xb" #'org-agenda-tree-to-indirect-buffer)
-(org-defkey org-agenda-mode-map "o" #'delete-other-windows)
-(org-defkey org-agenda-mode-map "L" #'org-agenda-recenter)
-(org-defkey org-agenda-mode-map "\C-c\C-t" #'org-agenda-todo)
-(org-defkey org-agenda-mode-map "t" #'org-agenda-todo)
-(org-defkey org-agenda-mode-map "a" #'org-agenda-archive-default-with-confirmation)
-(org-defkey org-agenda-mode-map ":" #'org-agenda-set-tags)
-(org-defkey org-agenda-mode-map "\C-c\C-q" #'org-agenda-set-tags)
-(org-defkey org-agenda-mode-map "." #'org-agenda-goto-today)
-(org-defkey org-agenda-mode-map "j" #'org-agenda-goto-date)
-(org-defkey org-agenda-mode-map "d" #'org-agenda-day-view)
-(org-defkey org-agenda-mode-map "w" #'org-agenda-week-view)
-(org-defkey org-agenda-mode-map "y" #'org-agenda-year-view)
-(org-defkey org-agenda-mode-map "\C-c\C-z" #'org-agenda-add-note)
-(org-defkey org-agenda-mode-map "z" #'org-agenda-add-note)
-(org-defkey org-agenda-mode-map [(shift right)] #'org-agenda-do-date-later)
-(org-defkey org-agenda-mode-map [(shift left)] #'org-agenda-do-date-earlier)
-(org-defkey org-agenda-mode-map [?\C-c ?\C-x (right)] #'org-agenda-do-date-later)
-(org-defkey org-agenda-mode-map [?\C-c ?\C-x (left)] #'org-agenda-do-date-earlier)
-(org-defkey org-agenda-mode-map ">" #'org-agenda-date-prompt)
-(org-defkey org-agenda-mode-map "\C-c\C-s" #'org-agenda-schedule)
-(org-defkey org-agenda-mode-map "\C-c\C-d" #'org-agenda-deadline)
-(let ((l '(1 2 3 4 5 6 7 8 9 0)))
- (while l (org-defkey org-agenda-mode-map
- (number-to-string (pop l)) #'digit-argument)))
-(org-defkey org-agenda-mode-map "F" #'org-agenda-follow-mode)
-(org-defkey org-agenda-mode-map "R" #'org-agenda-clockreport-mode)
-(org-defkey org-agenda-mode-map "E" #'org-agenda-entry-text-mode)
-(org-defkey org-agenda-mode-map "l" #'org-agenda-log-mode)
-(org-defkey org-agenda-mode-map "v" #'org-agenda-view-mode-dispatch)
-(org-defkey org-agenda-mode-map "D" #'org-agenda-toggle-diary)
-(org-defkey org-agenda-mode-map "!" #'org-agenda-toggle-deadlines)
-(org-defkey org-agenda-mode-map "G" #'org-agenda-toggle-time-grid)
-(org-defkey org-agenda-mode-map "r" #'org-agenda-redo)
-(org-defkey org-agenda-mode-map "g" #'org-agenda-redo-all)
-(org-defkey org-agenda-mode-map "e" #'org-agenda-set-effort)
-(org-defkey org-agenda-mode-map "\C-c\C-xe" #'org-agenda-set-effort)
-(org-defkey org-agenda-mode-map "\C-c\C-x\C-e"
- #'org-clock-modify-effort-estimate)
-(org-defkey org-agenda-mode-map "\C-c\C-xp" #'org-agenda-set-property)
-(org-defkey org-agenda-mode-map "q" #'org-agenda-quit)
-(org-defkey org-agenda-mode-map "Q" #'org-agenda-Quit)
-(org-defkey org-agenda-mode-map "x" #'org-agenda-exit)
-(org-defkey org-agenda-mode-map "\C-x\C-w" #'org-agenda-write)
-(org-defkey org-agenda-mode-map "\C-x\C-s" #'org-save-all-org-buffers)
-(org-defkey org-agenda-mode-map "s" #'org-save-all-org-buffers)
-(org-defkey org-agenda-mode-map "T" #'org-agenda-show-tags)
-(org-defkey org-agenda-mode-map "n" #'org-agenda-next-line)
-(org-defkey org-agenda-mode-map "p" #'org-agenda-previous-line)
-(org-defkey org-agenda-mode-map "N" #'org-agenda-next-item)
-(org-defkey org-agenda-mode-map "P" #'org-agenda-previous-item)
-(substitute-key-definition #'next-line #'org-agenda-next-line
- org-agenda-mode-map global-map)
-(substitute-key-definition #'previous-line #'org-agenda-previous-line
- org-agenda-mode-map global-map)
-(org-defkey org-agenda-mode-map "\C-c\C-a" #'org-attach)
-(org-defkey org-agenda-mode-map "\C-c\C-n" #'org-agenda-next-date-line)
-(org-defkey org-agenda-mode-map "\C-c\C-p" #'org-agenda-previous-date-line)
-(org-defkey org-agenda-mode-map "\C-c," #'org-agenda-priority)
-(org-defkey org-agenda-mode-map "," #'org-agenda-priority)
-(org-defkey org-agenda-mode-map "i" #'org-agenda-diary-entry)
-(org-defkey org-agenda-mode-map "c" #'org-agenda-goto-calendar)
-(org-defkey org-agenda-mode-map "C" #'org-agenda-convert-date)
-(org-defkey org-agenda-mode-map "M" #'org-agenda-phases-of-moon)
-(org-defkey org-agenda-mode-map "S" #'org-agenda-sunrise-sunset)
-(org-defkey org-agenda-mode-map "h" #'org-agenda-holidays)
-(org-defkey org-agenda-mode-map "H" #'org-agenda-holidays)
-(org-defkey org-agenda-mode-map "\C-c\C-x\C-i" #'org-agenda-clock-in)
-(org-defkey org-agenda-mode-map "I" #'org-agenda-clock-in)
-(org-defkey org-agenda-mode-map "\C-c\C-x\C-o" #'org-agenda-clock-out)
-(org-defkey org-agenda-mode-map "O" #'org-agenda-clock-out)
-(org-defkey org-agenda-mode-map "\C-c\C-x\C-x" #'org-agenda-clock-cancel)
-(org-defkey org-agenda-mode-map "X" #'org-agenda-clock-cancel)
-(org-defkey org-agenda-mode-map "\C-c\C-x\C-j" #'org-clock-goto)
-(org-defkey org-agenda-mode-map "J" #'org-agenda-clock-goto)
-(org-defkey org-agenda-mode-map "+" #'org-agenda-priority-up)
-(org-defkey org-agenda-mode-map "-" #'org-agenda-priority-down)
-(org-defkey org-agenda-mode-map [(shift up)] #'org-agenda-priority-up)
-(org-defkey org-agenda-mode-map [(shift down)] #'org-agenda-priority-down)
-(org-defkey org-agenda-mode-map [?\C-c ?\C-x (up)] #'org-agenda-priority-up)
-(org-defkey org-agenda-mode-map [?\C-c ?\C-x (down)] #'org-agenda-priority-down)
-(org-defkey org-agenda-mode-map "f" #'org-agenda-later)
-(org-defkey org-agenda-mode-map "b" #'org-agenda-earlier)
-(org-defkey org-agenda-mode-map "\C-c\C-x\C-c" #'org-agenda-columns)
-(org-defkey org-agenda-mode-map "\C-c\C-x>" #'org-agenda-remove-restriction-lock)
-(org-defkey org-agenda-mode-map "\C-c\C-x<" #'org-agenda-set-restriction-lock-from-agenda)
-(org-defkey org-agenda-mode-map "[" #'org-agenda-manipulate-query-add)
-(org-defkey org-agenda-mode-map "]" #'org-agenda-manipulate-query-subtract)
-(org-defkey org-agenda-mode-map "{" #'org-agenda-manipulate-query-add-re)
-(org-defkey org-agenda-mode-map "}" #'org-agenda-manipulate-query-subtract-re)
-(org-defkey org-agenda-mode-map "\\" #'org-agenda-filter-by-tag)
-(org-defkey org-agenda-mode-map "_" #'org-agenda-filter-by-effort)
-(org-defkey org-agenda-mode-map "=" #'org-agenda-filter-by-regexp)
-(org-defkey org-agenda-mode-map "/" #'org-agenda-filter)
-(org-defkey org-agenda-mode-map "|" #'org-agenda-filter-remove-all)
-(org-defkey org-agenda-mode-map "~" #'org-agenda-limit-interactively)
-(org-defkey org-agenda-mode-map "<" #'org-agenda-filter-by-category)
-(org-defkey org-agenda-mode-map "^" #'org-agenda-filter-by-top-headline)
-(org-defkey org-agenda-mode-map ";" #'org-timer-set-timer)
-(org-defkey org-agenda-mode-map "\C-c\C-x_" #'org-timer-stop)
-(org-defkey org-agenda-mode-map "?" #'org-agenda-show-the-flagging-note)
-(org-defkey org-agenda-mode-map "\C-c\C-x\C-mg" #'org-mobile-pull)
-(org-defkey org-agenda-mode-map "\C-c\C-x\C-mp" #'org-mobile-push)
-(org-defkey org-agenda-mode-map "\C-c\C-xI" #'org-info-find-node)
-(org-defkey org-agenda-mode-map [mouse-2] #'org-agenda-goto-mouse)
-(org-defkey org-agenda-mode-map [mouse-3] #'org-agenda-show-mouse)
-(org-defkey org-agenda-mode-map [remap forward-paragraph] #'org-agenda-forward-block)
-(org-defkey org-agenda-mode-map [remap backward-paragraph] #'org-agenda-backward-block)
-(org-defkey org-agenda-mode-map "\C-c\C-c" #'org-agenda-ctrl-c-ctrl-c)
-
-(when org-agenda-mouse-1-follows-link
- (org-defkey org-agenda-mode-map [follow-link] 'mouse-face))
-
-(easy-menu-define org-agenda-menu org-agenda-mode-map "Agenda menu."
- '("Agenda"
- ("Agenda Files")
- "--"
- ("Agenda Dates"
- ["Goto Today" org-agenda-goto-today (org-agenda-check-type nil 'agenda)]
- ["Next Dates" org-agenda-later (org-agenda-check-type nil 'agenda)]
- ["Previous Dates" org-agenda-earlier (org-agenda-check-type nil 'agenda)]
- ["Jump to date" org-agenda-goto-date (org-agenda-check-type nil 'agenda)])
- "--"
- ("View"
- ["Day View" org-agenda-day-view
- :active (org-agenda-check-type nil 'agenda)
- :style radio :selected (eq org-agenda-current-span 'day)
- :keys "v d (or just d)"]
- ["Week View" org-agenda-week-view
- :active (org-agenda-check-type nil 'agenda)
- :style radio :selected (eq org-agenda-current-span 'week)
- :keys "v w"]
- ["Fortnight View" org-agenda-fortnight-view
- :active (org-agenda-check-type nil 'agenda)
- :style radio :selected (eq org-agenda-current-span 'fortnight)
- :keys "v t"]
- ["Month View" org-agenda-month-view
- :active (org-agenda-check-type nil 'agenda)
- :style radio :selected (eq org-agenda-current-span 'month)
- :keys "v m"]
- ["Year View" org-agenda-year-view
- :active (org-agenda-check-type nil 'agenda)
- :style radio :selected (eq org-agenda-current-span 'year)
- :keys "v y"]
- "--"
- ["Include Diary" org-agenda-toggle-diary
- :style toggle :selected org-agenda-include-diary
- :active (org-agenda-check-type nil 'agenda)]
- ["Include Deadlines" org-agenda-toggle-deadlines
- :style toggle :selected org-agenda-include-deadlines
- :active (org-agenda-check-type nil 'agenda)]
- ["Use Time Grid" org-agenda-toggle-time-grid
- :style toggle :selected org-agenda-use-time-grid
- :active (org-agenda-check-type nil 'agenda)]
- "--"
- ["Show clock report" org-agenda-clockreport-mode
- :style toggle :selected org-agenda-clockreport-mode
- :active (org-agenda-check-type nil 'agenda)]
- ["Show some entry text" org-agenda-entry-text-mode
- :style toggle :selected org-agenda-entry-text-mode
- :active t]
- "--"
- ["Show Logbook entries" org-agenda-log-mode
- :style toggle :selected org-agenda-show-log
- :active (org-agenda-check-type nil 'agenda)
- :keys "v l (or just l)"]
- ["Include archived trees" org-agenda-archives-mode
- :style toggle :selected org-agenda-archives-mode :active t
- :keys "v a"]
- ["Include archive files" (org-agenda-archives-mode t)
- :style toggle :selected (eq org-agenda-archives-mode t) :active t
- :keys "v A"]
- "--"
- ["Remove Restriction" org-agenda-remove-restriction-lock org-agenda-restrict])
- ("Filter current view"
- ["with generic interface" org-agenda-filter t]
- "--"
- ["by category at cursor" org-agenda-filter-by-category t]
- ["by tag" org-agenda-filter-by-tag t]
- ["by effort" org-agenda-filter-by-effort t]
- ["by regexp" org-agenda-filter-by-regexp t]
- ["by top-level headline" org-agenda-filter-by-top-headline t]
- "--"
- ["Remove all filtering" org-agenda-filter-remove-all t]
- "--"
- ["limit" org-agenda-limit-interactively t])
- ["Rebuild buffer" org-agenda-redo t]
- ["Write view to file" org-agenda-write t]
- ["Save all Org buffers" org-save-all-org-buffers t]
- "--"
- ["Show original entry" org-agenda-show t]
- ["Go To (other window)" org-agenda-goto t]
- ["Go To (this window)" org-agenda-switch-to t]
- ["Capture with cursor date" org-agenda-capture t]
- ["Follow Mode" org-agenda-follow-mode
- :style toggle :selected org-agenda-follow-mode :active t]
- ;; ["Tree to indirect frame" org-agenda-tree-to-indirect-buffer t]
- "--"
- ("TODO"
- ["Cycle TODO" org-agenda-todo t]
- ["Next TODO set" org-agenda-todo-nextset t]
- ["Previous TODO set" org-agenda-todo-previousset t]
- ["Add note" org-agenda-add-note t])
- ("Archive/Refile/Delete"
- ["Archive default" org-agenda-archive-default t]
- ["Archive default" org-agenda-archive-default-with-confirmation t]
- ["Toggle ARCHIVE tag" org-agenda-toggle-archive-tag t]
- ["Move to archive sibling" org-agenda-archive-to-archive-sibling t]
- ["Archive subtree" org-agenda-archive t]
- "--"
- ["Refile" org-agenda-refile t]
- "--"
- ["Delete subtree" org-agenda-kill t])
- ("Bulk action"
- ["Mark entry" org-agenda-bulk-mark t]
- ["Mark all" org-agenda-bulk-mark-all t]
- ["Unmark entry" org-agenda-bulk-unmark t]
- ["Unmark all" org-agenda-bulk-unmark-all :active t :keys "U"]
- ["Toggle mark" org-agenda-bulk-toggle t]
- ["Toggle all" org-agenda-bulk-toggle-all t]
- ["Mark regexp" org-agenda-bulk-mark-regexp t])
- ["Act on all marked" org-agenda-bulk-action t]
- "--"
- ("Tags and Properties"
- ["Show all Tags" org-agenda-show-tags t]
- ["Set Tags current line" org-agenda-set-tags (not (org-region-active-p))]
- ["Change tag in region" org-agenda-set-tags (org-region-active-p)]
- "--"
- ["Column View" org-columns t])
- ("Deadline/Schedule"
- ["Schedule" org-agenda-schedule t]
- ["Set Deadline" org-agenda-deadline t]
- "--"
- ["Change Date +1 day" org-agenda-date-later (org-agenda-check-type nil 'agenda)]
- ["Change Date -1 day" org-agenda-date-earlier (org-agenda-check-type nil 'agenda)]
- ["Change Time +1 hour" org-agenda-do-date-later :active (org-agenda-check-type nil 'agenda) :keys "C-u S-right"]
- ["Change Time -1 hour" org-agenda-do-date-earlier :active (org-agenda-check-type nil 'agenda) :keys "C-u S-left"]
- ["Change Time + min" org-agenda-date-later :active (org-agenda-check-type nil 'agenda) :keys "C-u C-u S-right"]
- ["Change Time - min" org-agenda-date-earlier :active (org-agenda-check-type nil 'agenda) :keys "C-u C-u S-left"]
- ["Change Date to ..." org-agenda-date-prompt (org-agenda-check-type nil 'agenda)])
- ("Clock and Effort"
- ["Clock in" org-agenda-clock-in t]
- ["Clock out" org-agenda-clock-out t]
- ["Clock cancel" org-agenda-clock-cancel t]
- ["Goto running clock" org-clock-goto t]
- "--"
- ["Set Effort" org-agenda-set-effort t]
- ["Change clocked effort" org-clock-modify-effort-estimate
- (org-clock-is-active)])
- ("Priority"
- ["Set Priority" org-agenda-priority t]
- ["Increase Priority" org-agenda-priority-up t]
- ["Decrease Priority" org-agenda-priority-down t]
- ["Show Priority" org-priority-show t])
- ("Calendar/Diary"
- ["New Diary Entry" org-agenda-diary-entry (org-agenda-check-type nil 'agenda)]
- ["Goto Calendar" org-agenda-goto-calendar (org-agenda-check-type nil 'agenda)]
- ["Phases of the Moon" org-agenda-phases-of-moon (org-agenda-check-type nil 'agenda)]
- ["Sunrise/Sunset" org-agenda-sunrise-sunset (org-agenda-check-type nil 'agenda)]
- ["Holidays" org-agenda-holidays (org-agenda-check-type nil 'agenda)]
- ["Convert" org-agenda-convert-date (org-agenda-check-type nil 'agenda)]
- "--"
- ["Create iCalendar File" org-icalendar-combine-agenda-files t])
- "--"
- ["Undo Remote Editing" org-agenda-undo org-agenda-undo-list]
- "--"
- ("MobileOrg"
- ["Push Files and Views" org-mobile-push t]
- ["Get Captured and Flagged" org-mobile-pull t]
- ["Find FLAGGED Tasks" (org-agenda nil "?") :active t :keys "\\[org-agenda] ?"]
- ["Show note / unflag" org-agenda-show-the-flagging-note t]
- "--"
- ["Setup" (progn (require 'org-mobile) (customize-group 'org-mobile)) t])
- "--"
- ["Quit" org-agenda-quit t]
- ["Exit and Release Buffers" org-agenda-exit t]
- ))
-
-;;; Agenda undo
-
-(defvar org-agenda-allow-remote-undo t
- "Non-nil means allow remote undo from the agenda buffer.")
-(defvar org-agenda-undo-has-started-in nil
- "Buffers that have already seen `undo-start' in the current undo sequence.")
-
-(defun org-agenda-undo ()
- "Undo a remote editing step in the agenda.
-This undoes changes both in the agenda buffer and in the remote buffer
-that have been changed along."
- (interactive)
- (or org-agenda-allow-remote-undo
- (user-error "Check the variable `org-agenda-allow-remote-undo' to activate remote undo"))
- (when (not (eq this-command last-command))
- (setq org-agenda-undo-has-started-in nil
- org-agenda-pending-undo-list org-agenda-undo-list))
- (when (not org-agenda-pending-undo-list)
- (user-error "No further undo information"))
- (let* ((entry (pop org-agenda-pending-undo-list))
- buf line cmd rembuf)
- (setq cmd (pop entry) line (pop entry))
- (setq rembuf (nth 2 entry))
- (org-with-remote-undo rembuf
- (while (bufferp (setq buf (pop entry)))
- (when (pop entry)
- (with-current-buffer buf
- (let (;; (last-undo-buffer buf)
- (inhibit-read-only t))
- (unless (memq buf org-agenda-undo-has-started-in)
- (push buf org-agenda-undo-has-started-in)
- (make-local-variable 'pending-undo-list)
- (undo-start))
- (while (and pending-undo-list
- (listp pending-undo-list)
- (not (car pending-undo-list)))
- (pop pending-undo-list))
- (undo-more 1))))))
- (org-goto-line line)
- (message "`%s' undone (buffer %s)" cmd (buffer-name rembuf))))
-
-(defun org-verify-change-for-undo (l1 l2)
- "Verify that a real change occurred between the undo lists L1 and L2."
- (while (and l1 (listp l1) (null (car l1))) (pop l1))
- (while (and l2 (listp l2) (null (car l2))) (pop l2))
- (not (eq l1 l2)))
-
-;;; Agenda dispatch
-
-(defvar org-agenda-restrict-begin (make-marker))
-(defvar org-agenda-restrict-end (make-marker))
-(defvar org-agenda-last-dispatch-buffer nil)
-(defvar org-agenda-overriding-restriction nil)
-
-(defcustom org-agenda-custom-commands-contexts nil
- "Alist of custom agenda keys and contextual rules.
-
-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\\\\'\"))))
-
-Here are the available contexts definitions:
-
- in-file: command displayed only in matching files
- in-mode: command displayed only in matching modes
- not-in-file: command not displayed in matching files
- not-in-mode: command not displayed in matching modes
- in-buffer: command displayed only in matching buffers
-not-in-buffer: command not displayed in matching buffers
- [function]: a custom function taking no argument
-
-If you define several checks, the agenda command will be
-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\\\\'\"))))
-
-Here it means: in .txt files, use \"p\" as the key for the
-agenda command otherwise associated with \"q\". (The command
-originally associated with \"q\" is not displayed to avoid
-duplicates.)"
- :version "24.3"
- :group 'org-agenda-custom-commands
- :type '(repeat (list :tag "Rule"
- (string :tag " Agenda key")
- (string :tag "Replace by command")
- (repeat :tag "Available when"
- (choice
- (cons :tag "Condition"
- (choice
- (const :tag "In file" in-file)
- (const :tag "Not in file" not-in-file)
- (const :tag "In buffer" in-buffer)
- (const :tag "Not in buffer" not-in-buffer)
- (const :tag "In mode" in-mode)
- (const :tag "Not in mode" not-in-mode))
- (regexp))
- (function :tag "Custom function"))))))
-
-(defcustom org-agenda-max-entries nil
- "Maximum number of entries to display in an agenda.
-This can be nil (no limit) or an integer or an alist of agenda
-types with an associated number of entries to display in this
-type."
- :version "24.4"
- :package-version '(Org . "8.0")
- :group 'org-agenda-custom-commands
- :type '(choice (symbol :tag "No limit" nil)
- (integer :tag "Max number of entries")
- (repeat
- (cons (choice :tag "Agenda type"
- (const agenda)
- (const todo)
- (const tags)
- (const search))
- (integer :tag "Max number of entries")))))
-
-(defcustom org-agenda-max-todos nil
- "Maximum number of TODOs to display in an agenda.
-This can be nil (no limit) or an integer or an alist of agenda
-types with an associated number of entries to display in this
-type."
- :version "24.4"
- :package-version '(Org . "8.0")
- :group 'org-agenda-custom-commands
- :type '(choice (symbol :tag "No limit" nil)
- (integer :tag "Max number of TODOs")
- (repeat
- (cons (choice :tag "Agenda type"
- (const agenda)
- (const todo)
- (const tags)
- (const search))
- (integer :tag "Max number of TODOs")))))
-
-(defcustom org-agenda-max-tags nil
- "Maximum number of tagged entries to display in an agenda.
-This can be nil (no limit) or an integer or an alist of agenda
-types with an associated number of entries to display in this
-type."
- :version "24.4"
- :package-version '(Org . "8.0")
- :group 'org-agenda-custom-commands
- :type '(choice (symbol :tag "No limit" nil)
- (integer :tag "Max number of tagged entries")
- (repeat
- (cons (choice :tag "Agenda type"
- (const agenda)
- (const todo)
- (const tags)
- (const search))
- (integer :tag "Max number of tagged entries")))))
-
-(defcustom org-agenda-max-effort nil
- "Maximum cumulated effort duration for the agenda.
-This can be nil (no limit) or a number of minutes (as an integer)
-or an alist of agenda types with an associated number of minutes
-to limit entries to in this type."
- :version "24.4"
- :package-version '(Org . "8.0")
- :group 'org-agenda-custom-commands
- :type '(choice (symbol :tag "No limit" nil)
- (integer :tag "Max number of minutes")
- (repeat
- (cons (choice :tag "Agenda type"
- (const agenda)
- (const todo)
- (const tags)
- (const search))
- (integer :tag "Max number of minutes")))))
-
-(defvar org-agenda-keep-restricted-file-list nil)
-(defvar org-keys nil)
-(defvar org-match nil)
-;;;###autoload
-(defun org-agenda (&optional arg keys restriction)
- "Dispatch agenda commands to collect entries to the agenda buffer.
-Prompts for a command to execute. Any prefix arg will be passed
-on to the selected command. The default selections are:
-
-a Call `org-agenda-list' to display the agenda for current day or week.
-t Call `org-todo-list' to display the global todo list.
-T Call `org-todo-list' to display the global todo list, select only
- entries with a specific TODO keyword (the user gets a prompt).
-m Call `org-tags-view' to display headlines with tags matching
- a condition (the user is prompted for the condition).
-M Like `m', but select only TODO entries, no ordinary headlines.
-e Export views to associated files.
-s Search entries for keywords.
-S Search entries for keywords, only with TODO keywords.
-/ Multi occur across all agenda files and also files listed
- in `org-agenda-text-search-extra-files'.
-< Restrict agenda commands to buffer, subtree, or region.
- Press several times to get the desired effect.
-> Remove a previous restriction.
-# List \"stuck\" projects.
-! Configure what \"stuck\" means.
-C Configure custom agenda commands.
-
-More commands can be added by configuring the variable
-`org-agenda-custom-commands'. In particular, specific tags and TODO keyword
-searches can be pre-defined in this way.
-
-If the current buffer is in Org mode and visiting a file, you can also
-first press `<' once to indicate that the agenda should be temporarily
-\(until the next use of `\\[org-agenda]') restricted to the current file.
-Pressing `<' twice means to restrict to the current subtree or region
-\(if active)."
- (interactive "P")
- (catch 'exit
- (let* ((org-keys keys)
- (prefix-descriptions nil)
- (org-agenda-buffer-name org-agenda-buffer-name)
- (org-agenda-window-setup (if (equal (buffer-name)
- org-agenda-buffer-name)
- 'current-window
- org-agenda-window-setup))
- (org-agenda-custom-commands-orig org-agenda-custom-commands)
- (org-agenda-custom-commands
- ;; normalize different versions
- (delq nil
- (mapcar
- (lambda (x)
- (cond ((stringp (cdr x))
- (push x prefix-descriptions)
- nil)
- ((stringp (nth 1 x)) x)
- ((not (nth 1 x)) (cons (car x) (cons "" (cddr x))))
- (t (cons (car x) (cons "" (cdr x))))))
- org-agenda-custom-commands)))
- (org-agenda-custom-commands
- (org-contextualize-keys
- org-agenda-custom-commands org-agenda-custom-commands-contexts))
- ;; (buf (current-buffer))
- (bfn (buffer-file-name (buffer-base-buffer)))
- entry type org-match lprops ans) ;; key
- ;; Turn off restriction unless there is an overriding one,
- (unless org-agenda-overriding-restriction
- (unless org-agenda-keep-restricted-file-list
- ;; There is a request to keep the file list in place
- (put 'org-agenda-files 'org-restrict nil))
- (setq org-agenda-restrict nil)
- (move-marker org-agenda-restrict-begin nil)
- (move-marker org-agenda-restrict-end nil))
- ;; Delete old local properties
- (put 'org-agenda-redo-command 'org-lprops nil)
- ;; Delete previously set last-arguments
- (put 'org-agenda-redo-command 'last-args nil)
- ;; Remember where this call originated
- (setq org-agenda-last-dispatch-buffer (current-buffer))
- (unless org-keys
- (setq ans (org-agenda-get-restriction-and-command prefix-descriptions)
- org-keys (car ans)
- restriction (cdr ans)))
- ;; If we have sticky agenda buffers, set a name for the buffer,
- ;; depending on the invoking keys. The user may still set this
- ;; as a command option, which will overwrite what we do here.
- (when org-agenda-sticky
- (setq org-agenda-buffer-name
- (format "*Org Agenda(%s)*" org-keys)))
- ;; Establish the restriction, if any
- (when (and (not org-agenda-overriding-restriction) restriction)
- (put 'org-agenda-files 'org-restrict (list bfn))
- (cond
- ((eq restriction 'region)
- (setq org-agenda-restrict (current-buffer))
- (move-marker org-agenda-restrict-begin (region-beginning))
- (move-marker org-agenda-restrict-end (region-end)))
- ((eq restriction 'subtree)
- (save-excursion
- (setq org-agenda-restrict (current-buffer))
- (org-back-to-heading t)
- (move-marker org-agenda-restrict-begin (point))
- (move-marker org-agenda-restrict-end
- (progn (org-end-of-subtree t)))))
- ((and (eq restriction 'buffer)
- (or (< 1 (point-min))
- (< (point-max) (1+ (buffer-size)))))
- (setq org-agenda-restrict (current-buffer))
- (move-marker org-agenda-restrict-begin (point-min))
- (move-marker org-agenda-restrict-end (point-max)))))
-
- ;; For example the todo list should not need it (but does...)
- (cond
- ((setq entry (assoc org-keys org-agenda-custom-commands))
- (if (or (symbolp (nth 2 entry)) (functionp (nth 2 entry)))
- (progn
- ;; FIXME: Is (nth 3 entry) supposed to have access (via dynvars)
- ;; to some of the local variables? There's no doc about
- ;; that for `org-agenda-custom-commands'.
- (setq type (nth 2 entry) org-match (eval (nth 3 entry) t)
- lprops (nth 4 entry))
- (when org-agenda-sticky
- (setq org-agenda-buffer-name
- (or (and (stringp org-match) (format "*Org Agenda(%s:%s)*" org-keys org-match))
- (format "*Org Agenda(%s)*" org-keys))))
- (put 'org-agenda-redo-command 'org-lprops lprops)
- (cl-progv
- (mapcar #'car lprops)
- (mapcar (lambda (binding) (eval (cadr binding) t)) lprops)
- (pcase type
- (`agenda
- (org-agenda-list current-prefix-arg))
- (`agenda*
- (org-agenda-list current-prefix-arg nil nil t))
- (`alltodo
- (org-todo-list current-prefix-arg))
- (`search
- (org-search-view current-prefix-arg org-match nil))
- (`stuck
- (org-agenda-list-stuck-projects current-prefix-arg))
- (`tags
- (org-tags-view current-prefix-arg org-match))
- (`tags-todo
- (org-tags-view '(4) org-match))
- (`todo
- (org-todo-list org-match))
- (`tags-tree
- (org-check-for-org-mode)
- (org-match-sparse-tree current-prefix-arg org-match))
- (`todo-tree
- (org-check-for-org-mode)
- (org-occur (concat "^" org-outline-regexp "[ \t]*"
- (regexp-quote org-match) "\\>")))
- (`occur-tree
- (org-check-for-org-mode)
- (org-occur org-match))
- ((pred functionp)
- (funcall type org-match))
- ;; FIXME: Will signal an error since it's not `functionp'!
- ((pred fboundp) (funcall type org-match))
- (_ (user-error "Invalid custom agenda command type %s" type)))))
- (org-agenda-run-series (nth 1 entry) (cddr entry))))
- ((equal org-keys "C")
- (setq org-agenda-custom-commands org-agenda-custom-commands-orig)
- (customize-variable 'org-agenda-custom-commands))
- ((equal org-keys "a") (call-interactively 'org-agenda-list))
- ((equal org-keys "s") (call-interactively 'org-search-view))
- ((equal org-keys "S") (org-call-with-arg 'org-search-view (or arg '(4))))
- ((equal org-keys "t") (call-interactively 'org-todo-list))
- ((equal org-keys "T") (org-call-with-arg 'org-todo-list (or arg '(4))))
- ((equal org-keys "m") (call-interactively 'org-tags-view))
- ((equal org-keys "M") (org-call-with-arg 'org-tags-view (or arg '(4))))
- ((equal org-keys "e") (call-interactively 'org-store-agenda-views))
- ((equal org-keys "?") (org-tags-view nil "+FLAGGED")
- (add-hook
- 'post-command-hook
- (lambda ()
- (unless (current-message)
- (let* ((m (org-agenda-get-any-marker))
- (note (and m (org-entry-get m "THEFLAGGINGNOTE"))))
- (when note
- (message "FLAGGING-NOTE ([?] for more info): %s"
- (org-add-props
- (replace-regexp-in-string
- "\\\\n" "//"
- (copy-sequence note))
- nil 'face 'org-warning))))))
- t t))
- ((equal org-keys "#") (call-interactively 'org-agenda-list-stuck-projects))
- ((equal org-keys "/") (call-interactively 'org-occur-in-agenda-files))
- ((equal org-keys "!") (customize-variable 'org-stuck-projects))
- (t (user-error "Invalid agenda key"))))))
-
-(defvar org-agenda-multi)
-
-(defun org-agenda-append-agenda ()
- "Append another agenda view to the current one.
-This function allows interactive building of block agendas.
-Agenda views are separated by `org-agenda-block-separator'."
- (interactive)
- (unless (derived-mode-p 'org-agenda-mode)
- (user-error "Can only append from within agenda buffer"))
- (let ((org-agenda-multi t))
- (org-agenda)
- (widen)
- (org-agenda-finalize)
- (setq buffer-read-only t)
- (org-agenda-fit-window-to-buffer)))
-
-(defun org-agenda-normalize-custom-commands (cmds)
- "Normalize custom commands CMDS."
- (delq nil
- (mapcar
- (lambda (x)
- (cond ((stringp (cdr x)) nil)
- ((stringp (nth 1 x)) x)
- ((not (nth 1 x)) (cons (car x) (cons "" (cddr x))))
- (t (cons (car x) (cons "" (cdr x))))))
- cmds)))
-
-(defun org-agenda-get-restriction-and-command (prefix-descriptions)
- "The user interface for selecting an agenda command."
- (catch 'exit
- (let* ((bfn (buffer-file-name (buffer-base-buffer)))
- (restrict-ok (and bfn (derived-mode-p 'org-mode)))
- (region-p (org-region-active-p))
- (custom org-agenda-custom-commands)
- (selstring "")
- restriction second-time
- c entry key type match prefixes rmheader header-end custom1 desc
- line lines left right n n1)
- (save-window-excursion
- (delete-other-windows)
- (org-switch-to-buffer-other-window " *Agenda Commands*")
- (erase-buffer)
- (insert (eval-when-compile
- (let ((header
- (copy-sequence
- "Press key for an agenda command:
--------------------------------- < Buffer, subtree/region restriction
-a Agenda for current week or day > Remove restriction
-t List of all TODO entries e Export agenda views
-m Match a TAGS/PROP/TODO query T Entries with special TODO kwd
-s Search for keywords M Like m, but only TODO entries
-/ Multi-occur S Like s, but only TODO entries
-? Find :FLAGGED: entries C Configure custom agenda commands
-* Toggle sticky agenda views # List stuck projects (!=configure)
-"))
- (start 0))
- (while (string-match
- "\\(^\\| \\|(\\)\\(\\S-\\)\\( \\|=\\)"
- header start)
- (setq start (match-end 0))
- (add-text-properties (match-beginning 2) (match-end 2)
- '(face bold) header))
- header)))
- (setq header-end (point-marker))
- (while t
- (setq custom1 custom)
- (when (eq rmheader t)
- (org-goto-line 1)
- (re-search-forward ":" nil t)
- (delete-region (match-end 0) (point-at-eol))
- (forward-char 1)
- (looking-at "-+")
- (delete-region (match-end 0) (point-at-eol))
- (move-marker header-end (match-end 0)))
- (goto-char header-end)
- (delete-region (point) (point-max))
-
- ;; Produce all the lines that describe custom commands and prefixes
- (setq lines nil)
- (while (setq entry (pop custom1))
- (setq key (car entry) desc (nth 1 entry)
- type (nth 2 entry)
- match (nth 3 entry))
- (if (> (length key) 1)
- (cl-pushnew (string-to-char key) prefixes :test #'equal)
- (setq line
- (format
- "%-4s%-14s"
- (org-add-props (copy-sequence key)
- '(face bold))
- (cond
- ((string-match "\\S-" desc) desc)
- ((eq type 'agenda) "Agenda for current week or day")
- ((eq type 'agenda*) "Appointments for current week or day")
- ((eq type 'alltodo) "List of all TODO entries")
- ((eq type 'search) "Word search")
- ((eq type 'stuck) "List of stuck projects")
- ((eq type 'todo) "TODO keyword")
- ((eq type 'tags) "Tags query")
- ((eq type 'tags-todo) "Tags (TODO)")
- ((eq type 'tags-tree) "Tags tree")
- ((eq type 'todo-tree) "TODO kwd tree")
- ((eq type 'occur-tree) "Occur tree")
- ((functionp type) (if (symbolp type)
- (symbol-name type)
- "Lambda expression"))
- (t "???"))))
- (cond
- ((not (org-string-nw-p match)) nil)
- (org-agenda-menu-show-matcher
- (setq line
- (concat line ": "
- (cond
- ((stringp match)
- (propertize match 'face 'org-warning))
- ((listp type)
- (format "set of %d commands" (length type)))))))
- (t
- (org-add-props line nil 'help-echo (concat "Matcher: " match))))
- (push line lines)))
- (setq lines (nreverse lines))
- (when prefixes
- (mapc (lambda (x)
- (push
- (format "%s %s"
- (org-add-props (char-to-string x)
- nil 'face 'bold)
- (or (cdr (assoc (concat selstring
- (char-to-string x))
- prefix-descriptions))
- "Prefix key"))
- lines))
- prefixes))
-
- ;; Check if we should display in two columns
- (if org-agenda-menu-two-columns
- (progn
- (setq n (length lines)
- n1 (+ (/ n 2) (mod n 2))
- right (nthcdr n1 lines)
- left (copy-sequence lines))
- (setcdr (nthcdr (1- n1) left) nil))
- (setq left lines right nil))
- (while left
- (insert "\n" (pop left))
- (when right
- (if (< (current-column) 40)
- (move-to-column 40 t)
- (insert " "))
- (insert (pop right))))
-
- ;; Make the window the right size
- (goto-char (point-min))
- (if second-time
- (when (not (pos-visible-in-window-p (point-max)))
- (org-fit-window-to-buffer))
- (setq second-time t)
- (org-fit-window-to-buffer))
-
- ;; Hint to navigation if window too small for all information
- (setq header-line-format
- (when (not (pos-visible-in-window-p (point-max)))
- "Use C-v, M-v, C-n or C-p to navigate."))
-
- ;; Ask for selection
- (cl-loop
- do (progn
- (message "Press key for agenda command%s:"
- (if (or restrict-ok org-agenda-overriding-restriction)
- (if org-agenda-overriding-restriction
- " (restriction lock active)"
- (if restriction
- (format " (restricted to %s)" restriction)
- " (unrestricted)"))
- ""))
- (setq c (read-char-exclusive)))
- until (not (memq c '(14 16 22 134217846)))
- do (org-scroll c))
-
- (message "")
- (cond
- ((assoc (char-to-string c) custom)
- (setq selstring (concat selstring (char-to-string c)))
- (throw 'exit (cons selstring restriction)))
- ((memq c prefixes)
- (setq selstring (concat selstring (char-to-string c))
- prefixes nil
- rmheader (or rmheader t)
- custom (delq nil (mapcar
- (lambda (x)
- (if (or (= (length (car x)) 1)
- (/= (string-to-char (car x)) c))
- nil
- (cons (substring (car x) 1) (cdr x))))
- custom))))
- ((eq c ?*)
- (call-interactively 'org-toggle-sticky-agenda)
- (sit-for 2))
- ((and (not restrict-ok) (memq c '(?1 ?0 ?<)))
- (message "Restriction is only possible in Org buffers")
- (ding) (sit-for 1))
- ((eq c ?1)
- (org-agenda-remove-restriction-lock 'noupdate)
- (setq restriction 'buffer))
- ((eq c ?0)
- (org-agenda-remove-restriction-lock 'noupdate)
- (setq restriction (if region-p 'region 'subtree)))
- ((eq c ?<)
- (org-agenda-remove-restriction-lock 'noupdate)
- (setq restriction
- (cond
- ((eq restriction 'buffer)
- (if region-p 'region 'subtree))
- ((memq restriction '(subtree region))
- nil)
- (t 'buffer))))
- ((eq c ?>)
- (org-agenda-remove-restriction-lock 'noupdate)
- (setq restriction nil))
- ((and (equal selstring "") (memq c '(?s ?S ?a ?t ?m ?L ?C ?e ?T ?M ?# ?! ?/ ??)))
- (throw 'exit (cons (setq selstring (char-to-string c)) restriction)))
- ((and (> (length selstring) 0) (eq c ?\d))
- (delete-window)
- (org-agenda-get-restriction-and-command prefix-descriptions))
-
- ((equal c ?q) (user-error "Abort"))
- (t (user-error "Invalid key %c" c))))))))
-
-(defun org-agenda-fit-window-to-buffer ()
- "Fit the window to the buffer size."
- (and (memq org-agenda-window-setup '(reorganize-frame))
- (fboundp 'fit-window-to-buffer)
- (if (and (= (cdr org-agenda-window-frame-fractions) 1.0)
- (= (car org-agenda-window-frame-fractions) 1.0))
- (delete-other-windows)
- (org-fit-window-to-buffer
- nil
- (floor (* (frame-height) (cdr org-agenda-window-frame-fractions)))
- (floor (* (frame-height) (car org-agenda-window-frame-fractions)))))))
-
-(defvar org-cmd nil)
-(defvar org-agenda-overriding-cmd nil)
-(defvar org-agenda-overriding-arguments nil)
-(defvar org-agenda-overriding-cmd-arguments nil)
-
-(defun org-let (list &rest body) ;FIXME: So many kittens are suffering here.
- (declare (indent 1) (obsolete cl-progv "2021"))
- (eval (cons 'let (cons list body))))
-
-(defun org-let2 (list1 list2 &rest body) ;FIXME: Where did our karma go?
- (declare (indent 2) (obsolete cl-progv "2021"))
- (eval (cons 'let (cons list1 (list (cons 'let (cons list2 body)))))))
-
-(defun org-agenda-run-series (name series)
- "Run agenda NAME as a SERIES of agenda commands."
- (let* ((gprops (nth 1 series))
- (gvars (mapcar #'car gprops))
- (gvals (mapcar (lambda (binding) (eval (cadr binding) t)) gprops)))
- (cl-progv gvars gvals (org-agenda-prepare name))
- ;; We need to reset agenda markers here, because when constructing a
- ;; block agenda, the individual blocks do not do that.
- (org-agenda-reset-markers)
- (with-no-warnings
- (defvar match)) ;Used via the `eval' below.
- (let* ((org-agenda-multi t)
- ;; FIXME: Redo should contain lists of (FUNS . ARGS) rather
- ;; than expressions, so you don't need to `quote' the args
- ;; and you just need to `apply' instead of `eval' when using it.
- (redo (list 'org-agenda-run-series name (list 'quote series)))
- (cmds (car series))
- match
- org-cmd type lprops)
- (while (setq org-cmd (pop cmds))
- (setq type (car org-cmd))
- (setq match (eval (nth 1 org-cmd) t))
- (setq lprops (nth 2 org-cmd))
- (let ((org-agenda-overriding-arguments
- (if (eq org-agenda-overriding-cmd org-cmd)
- (or org-agenda-overriding-arguments
- org-agenda-overriding-cmd-arguments)))
- (lvars (mapcar #'car lprops))
- (lvals (mapcar (lambda (binding) (eval (cadr binding) t)) lprops)))
- (cl-progv (append gvars lvars) (append gvals lvals)
- (pcase type
- (`agenda
- (call-interactively 'org-agenda-list))
- (`agenda*
- (funcall 'org-agenda-list nil nil t))
- (`alltodo
- (call-interactively 'org-todo-list))
- (`search
- (org-search-view current-prefix-arg match nil))
- (`stuck
- (call-interactively 'org-agenda-list-stuck-projects))
- (`tags
- (org-tags-view current-prefix-arg match))
- (`tags-todo
- (org-tags-view '(4) match))
- (`todo
- (org-todo-list match))
- ((pred fboundp)
- (funcall type match))
- (_ (error "Invalid type in command series"))))))
- (widen)
- (let ((inhibit-read-only t))
- (add-text-properties (point-min) (point-max)
- `(org-series t org-series-redo-cmd ,redo)))
- (setq org-agenda-redo-command redo)
- (goto-char (point-min)))
- (org-agenda-fit-window-to-buffer)
- (cl-progv gvars gvals (org-agenda-finalize))))
-
-(defun org-agenda--split-plist (plist)
- ;; We could/should arguably use `map-keys' and `map-values'.
- (let (keys vals)
- (while plist
- (push (pop plist) keys)
- (push (pop plist) vals))
- (cons (nreverse keys) (nreverse vals))))
-
-;;;###autoload
-(defmacro org-batch-agenda (cmd-key &rest parameters)
- "Run an agenda command in batch mode and send the result to STDOUT.
-If CMD-KEY is a string of length 1, it is used as a key in
-`org-agenda-custom-commands' and triggers this command. If it is a
-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."
- (pcase-let ((`(,vars . ,exps) (org-agenda--split-plist parameters)))
- `(org--batch-agenda ,cmd-key ',vars (list ,@exps))))
-
-(defun org--batch-agenda (cmd-key vars vals)
- ;; `org-batch-agenda' is a macro because every other "parameter" is
- ;; a variable name rather than an expression to evaluate. Yuck!
- (cl-progv vars vals
- (let (org-agenda-sticky)
- (if (> (length cmd-key) 1)
- (org-tags-view nil cmd-key)
- (org-agenda nil cmd-key))))
- (set-buffer org-agenda-buffer-name)
- (princ (buffer-string)))
-
-(defvar org-agenda-info nil)
-
-;;;###autoload
-(defmacro org-batch-agenda-csv (cmd-key &rest parameters)
- "Run an agenda command in batch mode and send the result to STDOUT.
-If CMD-KEY is a string of length 1, it is used as a key in
-`org-agenda-custom-commands' and triggers this command. If it is a
-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.
-
-The output gives a line for each selected agenda item. Each
-item is a list of comma-separated values, like this:
-
-category,head,type,todo,tags,date,time,extra,priority-l,priority-n
-
-category The category of the item
-head The headline, without TODO kwd, TAGS and PRIORITY
-type The type of the agenda entry, can be
- todo selected in TODO match
- tagsmatch selected in tags match
- diary imported from diary
- deadline a deadline on given date
- scheduled scheduled on given date
- timestamp entry has timestamp on given date
- closed entry was closed on given date
- upcoming-deadline warning about deadline
- past-scheduled forwarded scheduled item
- block entry has date block including g. date
-todo The todo keyword, if any
-tags All tags including inherited ones, separated by colons
-date The relevant date, like 2007-2-14
-time The time, like 15:00-16:50
-extra String 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"
- (pcase-let ((`(,vars . ,exps) (org-agenda--split-plist parameters)))
- `(org--batch-agenda-csv ,cmd-key ',vars (list ,@exps))))
-
-(defun org--batch-agenda-csv (cmd-key vars vals)
- ;; `org-batch-agenda-csv' is a macro because every other "parameter" is
- ;; a variable name rather than an expression to evaluate. Yuck!
- (let ((org-agenda-remove-tags t))
- (cl-progv vars vals
- ;; FIXME: Shouldn't this be 1 (see commit 10173ad6d610b)?
- (if (> (length cmd-key) 2)
- (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")))
- (dolist (line lines)
- (when (get-text-property 0 'org-category line)
- (setq org-agenda-info
- (org-fix-agenda-info (text-properties-at 0 line)))
- (princ
- (mapconcat #'org-agenda-export-csv-mapper
- '(org-category txt type todo tags date time extra
- priority-letter priority agenda-day)
- ","))
- (princ "\n")))))
-
-(defun org-fix-agenda-info (props)
- "Make sure all properties on an agenda item have a canonical form.
-This ensures the export commands can easily use it."
- (let (tmp re)
- (when (setq tmp (plist-get props 'tags))
- (setq props (plist-put props 'tags (mapconcat #'identity tmp ":"))))
- (when (setq tmp (plist-get props 'date))
- (when (integerp tmp) (setq tmp (calendar-gregorian-from-absolute tmp)))
- (let ((calendar-date-display-form '(year "-" month "-" day)))
- '((format "%4d, %9s %2s, %4s" dayname monthname day year))
-
- (setq tmp (calendar-date-string tmp)))
- (setq props (plist-put props 'date tmp)))
- (when (setq tmp (plist-get props 'day))
- (when (integerp tmp) (setq tmp (calendar-gregorian-from-absolute tmp)))
- (let ((calendar-date-display-form '(year "-" month "-" day)))
- (setq tmp (calendar-date-string tmp)))
- (setq props (plist-put props 'day tmp))
- (setq props (plist-put props 'agenda-day tmp)))
- (when (setq tmp (plist-get props 'txt))
- (when (string-match "\\[#\\([A-Z0-9]\\)\\] ?" tmp)
- (plist-put props 'priority-letter (match-string 1 tmp))
- (setq tmp (replace-match "" t t tmp)))
- (when (and (setq re (plist-get props 'org-todo-regexp))
- (setq re (concat "\\`\\.*" re " ?"))
- (let ((case-fold-search nil)) (string-match re tmp)))
- (plist-put props 'todo (match-string 1 tmp))
- (setq tmp (replace-match "" t t tmp)))
- (plist-put props 'txt tmp)))
- props)
-
-(defun org-agenda-export-csv-mapper (prop)
- (let ((res (plist-get org-agenda-info prop)))
- (setq res
- (cond
- ((not res) "")
- ((stringp res) res)
- (t (prin1-to-string res))))
- (org-trim (replace-regexp-in-string "," ";" res nil t))))
-
-;;;###autoload
-(defun org-store-agenda-views (&rest _parameters)
- "Store agenda views."
- (interactive)
- (org--batch-store-agenda-views nil nil))
-
-;;;###autoload
-(defmacro org-batch-store-agenda-views (&rest parameters)
- "Run all custom agenda commands that have a file argument."
- (pcase-let ((`(,vars . ,exps) (org-agenda--split-plist parameters)))
- `(org--batch-store-agenda-views ',vars (list ,@exps))))
-
-(defun org--batch-store-agenda-views (vars vals)
- (let ((cmds (org-agenda-normalize-custom-commands org-agenda-custom-commands))
- (pop-up-frames nil)
- (dir default-directory)
- cmd thiscmdkey thiscmdcmd match files opts cmd-or-set bufname)
- (save-window-excursion
- (while cmds
- (setq cmd (pop cmds)
- thiscmdkey (car cmd)
- thiscmdcmd (cdr cmd)
- match (nth 2 thiscmdcmd)
- bufname (if org-agenda-sticky
- (or (and (stringp match)
- (format "*Org Agenda(%s:%s)*" thiscmdkey match))
- (format "*Org Agenda(%s)*" thiscmdkey))
- org-agenda-buffer-name)
- cmd-or-set (nth 2 cmd)
- opts (nth (if (listp cmd-or-set) 3 4) cmd)
- files (nth (if (listp cmd-or-set) 4 5) cmd))
- (if (stringp files) (setq files (list files)))
- (when files
- (let* ((opts (append org-agenda-exporter-settings opts))
- (vars (append (mapcar #'car opts) vars))
- (vals (append (mapcar (lambda (binding) (eval (cadr binding) t))
- opts)
- vals)))
- (cl-progv vars vals
- (org-agenda nil thiscmdkey))
- (set-buffer bufname)
- (while files
- (cl-progv vars vals
- (org-agenda-write (expand-file-name (pop files) dir)
- nil t bufname))))
- (and (get-buffer bufname)
- (kill-buffer bufname)))))))
-
-(defvar org-agenda-current-span nil
- "The current span used in the agenda view.") ; local variable in the agenda buffer
-(defun org-agenda-mark-header-line (pos)
- "Mark the line at POS as an agenda structure header."
- (save-excursion
- (goto-char pos)
- (put-text-property (point-at-bol) (point-at-eol)
- 'org-agenda-structural-header t)
- (when org-agenda-title-append
- (put-text-property (point-at-bol) (point-at-eol)
- 'org-agenda-title-append org-agenda-title-append))))
-
-(defvar org-mobile-creating-agendas) ; defined in org-mobile.el
-(defvar org-agenda-write-buffer-name "Agenda View")
-(defun org-agenda-write (file &optional open nosettings agenda-bufname)
- "Write the current buffer (an agenda view) as a file.
-
-Depending on the extension of the file name, plain text (.txt),
-HTML (.html or .htm), PDF (.pdf) or Postscript (.ps) is produced.
-If the extension is .ics, translate visible agenda into iCalendar
-format. If the extension is .org, collect all subtrees
-corresponding to the agenda entries and add them in an .org file.
-
-With prefix argument OPEN, open the new file immediately. If
-NOSETTINGS is given, do not scope the settings of
-`org-agenda-exporter-settings' into the export commands. This is
-used when the settings have already been scoped and we do not
-wish to overrule other, higher priority settings. If
-AGENDA-BUFFER-NAME is provided, use this as the buffer name for
-the agenda to write."
- (interactive "FWrite agenda to file: \nP")
- (if (or (not (file-writable-p file))
- (and (file-exists-p file)
- (if (called-interactively-p 'any)
- (not (y-or-n-p (format "Overwrite existing file %s? " file))))))
- (user-error "Cannot write agenda to file %s" file))
- (cl-progv
- (if nosettings nil (mapcar #'car org-agenda-exporter-settings))
- (if nosettings nil (mapcar (lambda (binding) (eval (cadr binding) t))
- org-agenda-exporter-settings))
- (save-excursion
- (save-window-excursion
- (let ((bs (copy-sequence (buffer-string)))
- (extension (file-name-extension file))
- (default-directory (file-name-directory file))
- ) ;; beg content
- (with-temp-buffer
- (rename-buffer org-agenda-write-buffer-name t)
- (set-buffer-modified-p nil)
- (insert bs)
- (org-agenda-remove-marked-text 'invisible 'org-filtered)
- (run-hooks 'org-agenda-before-write-hook)
- (cond
- ((bound-and-true-p org-mobile-creating-agendas)
- (org-mobile-write-agenda-for-mobile file))
- ((string= "org" extension)
- (let (content p m message-log-max)
- (goto-char (point-min))
- (while (setq p (next-single-property-change (point) 'org-hd-marker nil))
- (goto-char p)
- (setq m (get-text-property (point) 'org-hd-marker))
- (when m
- (push (with-current-buffer (marker-buffer m)
- (goto-char m)
- (org-copy-subtree 1 nil t t)
- org-subtree-clip)
- content)))
- (find-file file)
- (erase-buffer)
- (dolist (s content) (org-paste-subtree 1 s))
- (write-file file)
- (kill-buffer (current-buffer))
- (message "Org file written to %s" file)))
- ((member extension '("html" "htm"))
- (or (require 'htmlize nil t)
- (error "Please install htmlize from https://github.com/hniksic/emacs-htmlize"))
- (declare-function htmlize-buffer "htmlize" (&optional buffer))
- (set-buffer (htmlize-buffer (current-buffer)))
- (when org-agenda-export-html-style
- ;; replace <style> section with org-agenda-export-html-style
- (goto-char (point-min))
- (kill-region (- (search-forward "<style") 6)
- (search-forward "</style>"))
- (insert org-agenda-export-html-style))
- (write-file file)
- (kill-buffer (current-buffer))
- (message "HTML written to %s" file))
- ((string= "ps" extension)
- (require 'ps-print)
- (ps-print-buffer-with-faces file)
- (message "Postscript written to %s" file))
- ((string= "pdf" extension)
- (require 'ps-print)
- (ps-print-buffer-with-faces
- (concat (file-name-sans-extension file) ".ps"))
- (call-process "ps2pdf" nil nil nil
- (expand-file-name
- (concat (file-name-sans-extension file) ".ps"))
- (expand-file-name file))
- (delete-file (concat (file-name-sans-extension file) ".ps"))
- (message "PDF written to %s" file))
- ((string= "ics" extension)
- (require 'ox-icalendar)
- (declare-function org-icalendar-export-current-agenda
- "ox-icalendar" (file))
- (org-icalendar-export-current-agenda (expand-file-name file)))
- (t
- (let ((bs (buffer-string)))
- (find-file file)
- (erase-buffer)
- (insert bs)
- (save-buffer 0)
- (kill-buffer (current-buffer))
- (message "Plain text written to %s" file))))))))
- (set-buffer (or agenda-bufname
- ;; FIXME: I'm pretty sure called-interactively-p
- ;; doesn't do what we want here!
- (and (called-interactively-p 'any) (buffer-name))
- org-agenda-buffer-name)))
- (when open (org-open-file file)))
-
-(defun org-agenda-remove-marked-text (property &optional value)
- "Delete all text marked with VALUE of PROPERTY.
-VALUE defaults to t."
- (let (beg)
- (setq value (or value t))
- (while (setq beg (text-property-any (point-min) (point-max)
- property value))
- (delete-region
- beg (or (next-single-property-change beg property)
- (point-max))))))
-
-(defun org-agenda-add-entry-text ()
- "Add entry text to agenda lines.
-This will add a maximum of `org-agenda-add-entry-text-maxlines' lines of the
-entry text following headings shown in the agenda.
-Drawers will be excluded, also the line with scheduling/deadline info."
- (when (and (> org-agenda-add-entry-text-maxlines 0)
- (not (bound-and-true-p org-mobile-creating-agendas)))
- (let (m txt)
- (goto-char (point-min))
- (while (not (eobp))
- (if (not (setq m (org-get-at-bol 'org-hd-marker)))
- (beginning-of-line 2)
- (setq txt (org-agenda-get-some-entry-text
- m org-agenda-add-entry-text-maxlines " > "))
- (end-of-line 1)
- (if (string-match "\\S-" txt)
- (insert "\n" txt)
- (or (eobp) (forward-char 1))))))))
-
-(defun org-agenda-get-some-entry-text (marker n-lines &optional indent
- &rest keep)
- "Extract entry text from MARKER, at most N-LINES lines.
-This will ignore drawers etc, just get the text.
-If INDENT is given, prefix every line with this string. If KEEP is
-given, it is a list of symbols, defining stuff that should not be
-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 (derived-mode-p 'org-mode))
- (setq txt "")
- (org-with-wide-buffer
- (goto-char marker)
- (end-of-line 1)
- (setq txt (buffer-substring
- (min (1+ (point)) (point-max))
- (progn (outline-next-heading) (point)))
- drawer-re org-drawer-regexp
- kwd-time-re (concat "^[ \t]*" org-keyword-time-regexp
- ".*\n?"))
- (with-temp-buffer
- (insert txt)
- (when org-agenda-add-entry-text-descriptive-links
- (goto-char (point-min))
- (while (org-activate-links (point-max))
- (goto-char (match-end 0))))
- (goto-char (point-min))
- (while (re-search-forward org-link-bracket-re (point-max) t)
- (set-text-properties (match-beginning 0) (match-end 0)
- nil))
- (goto-char (point-min))
- (while (re-search-forward drawer-re nil t)
- (delete-region
- (match-beginning 0)
- (progn (re-search-forward
- "^[ \t]*:END:.*\n?" nil 'move)
- (point))))
- (unless (member 'planning keep)
- (goto-char (point-min))
- (while (re-search-forward kwd-time-re nil t)
- (replace-match "")))
- (goto-char (point-min))
- (when org-agenda-entry-text-exclude-regexps
- (let ((re-list org-agenda-entry-text-exclude-regexps) re)
- (while (setq re (pop re-list))
- (goto-char (point-min))
- (while (re-search-forward re nil t)
- (replace-match "")))))
- (goto-char (point-max))
- (skip-chars-backward " \t\n")
- (when (looking-at "[ \t\n]+\\'") (replace-match ""))
-
- ;; find and remove min common indentation
- (goto-char (point-min))
- (untabify (point-min) (point-max))
- (setq ind (current-indentation))
- (while (not (eobp))
- (unless (looking-at "[ \t]*$")
- (setq ind (min ind (current-indentation))))
- (beginning-of-line 2))
- (goto-char (point-min))
- (while (not (eobp))
- (unless (looking-at "[ \t]*$")
- (move-to-column ind)
- (delete-region (point-at-bol) (point)))
- (beginning-of-line 2))
-
- (run-hooks 'org-agenda-entry-text-cleanup-hook)
-
- (goto-char (point-min))
- (when indent
- (while (and (not (eobp)) (re-search-forward "^" nil t))
- (replace-match indent t t)))
- (goto-char (point-min))
- (while (looking-at "[ \t]*\n") (replace-match ""))
- (goto-char (point-max))
- (when (> (org-current-line)
- n-lines)
- (org-goto-line (1+ n-lines))
- (backward-char 1))
- (setq txt (buffer-substring (point-min) (point))))))))
- txt))
-
-(defun org-check-for-org-mode ()
- "Make sure current buffer is in Org mode. Error if not."
- (or (derived-mode-p 'org-mode)
- (error "Cannot execute Org agenda command on buffer in %s"
- major-mode)))
-
-;;; Agenda prepare and finalize
-
-(defvar org-agenda-multi nil) ; dynamically scoped
-(defvar org-agenda-pre-window-conf nil)
-(defvar org-agenda-columns-active nil)
-(defvar org-agenda-name nil)
-(defvar org-agenda-tag-filter nil)
-(defvar org-agenda-category-filter nil)
-(defvar org-agenda-regexp-filter nil)
-(defvar org-agenda-effort-filter nil)
-(defvar org-agenda-top-headline-filter nil)
-
-(defvar org-agenda-represented-categories nil
- "Cache for the list of all categories in the agenda.")
-(defvar org-agenda-represented-tags nil
- "Cache for the list of all categories in the agenda.")
-(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
-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
-the entire agenda view. In a block agenda, it will not work reliably to
-define a filter for one of the individual blocks. You need to set it in
-the global options and expect it to be applied to the entire view.")
-
-(defconst org-agenda-filter-variables
- '((category . org-agenda-category-filter)
- (tag . org-agenda-tag-filter)
- (effort . org-agenda-effort-filter)
- (regexp . org-agenda-regexp-filter))
- "Alist of filter types and associated variables.")
-(defun org-agenda-filter-any ()
- "Is any filter active?"
- (cl-some (lambda (x)
- (or (symbol-value (cdr x))
- (get :preset-filter x)))
- org-agenda-filter-variables))
-
-(defvar org-agenda-category-filter-preset nil
- "A preset of the category filter used for secondary agenda filtering.
-This must be a list of strings, each string must be a single category
-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
-the entire agenda view. In a block agenda, it will not work reliably to
-define a filter for one of the individual blocks. You need to set it in
-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 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
-the entire agenda view. In a block agenda, it will not work reliably to
-define a filter for one of the individual blocks. You need to set it in
-the global options and expect it to be applied to the entire view.")
-
-(defvar org-agenda-effort-filter-preset nil
- "A preset of the effort condition used for secondary agenda filtering.
-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
-the entire agenda view. In a block agenda, it will not work reliably to
-define a filter for one of the individual blocks. You need to set it in
-the global options and expect it to be applied to the entire view.")
-
-(defun org-agenda-use-sticky-p ()
- "Return non-nil if an agenda buffer named
-`org-agenda-buffer-name' exists and should be shown instead of
-generating a new one."
- (and
- ;; turned off by user
- org-agenda-sticky
- ;; For multi-agenda buffer already exists
- (not org-agenda-multi)
- ;; buffer found
- (get-buffer org-agenda-buffer-name)
- ;; C-u parameter is same as last call
- (with-current-buffer (get-buffer org-agenda-buffer-name)
- (and
- (equal current-prefix-arg
- org-agenda-last-prefix-arg)
- ;; In case user turned stickiness on, while having existing
- ;; Agenda buffer active, don't reuse that buffer, because it
- ;; does not have org variables local
- org-agenda-this-buffer-is-sticky))))
-
-(defvar org-agenda-buffer-tmp-name nil)
-
-(defun org-agenda--get-buffer-name (sticky-name)
- (or org-agenda-buffer-tmp-name
- (and org-agenda-doing-sticky-redo org-agenda-buffer-name)
- sticky-name
- "*Org Agenda*"))
-
-(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))
- ((not (setq wconf (current-window-configuration))))
- ((eq org-agenda-window-setup 'current-window)
- (pop-to-buffer-same-window abuf))
- ((eq org-agenda-window-setup 'other-window)
- (org-switch-to-buffer-other-window abuf))
- ((eq org-agenda-window-setup 'other-frame)
- (switch-to-buffer-other-frame abuf))
- ((eq org-agenda-window-setup 'other-tab)
- (if (fboundp 'switch-to-buffer-other-tab)
- (switch-to-buffer-other-tab abuf)
- (user-error "Your version of Emacs does not have tab bar support")))
- ((eq org-agenda-window-setup 'only-window)
- (delete-other-windows)
- (pop-to-buffer-same-window abuf))
- ((eq org-agenda-window-setup 'reorganize-frame)
- (delete-other-windows)
- (org-switch-to-buffer-other-window abuf)))
- (setq org-agenda-tag-filter (cdr (assq 'tag filter-alist)))
- (setq org-agenda-category-filter (cdr (assq 'cat filter-alist)))
- (setq org-agenda-effort-filter (cdr (assq 'effort filter-alist)))
- (setq org-agenda-regexp-filter (cdr (assq 're filter-alist)))
- ;; Additional test in case agenda is invoked from within agenda
- ;; buffer via elisp link.
- (unless (equal (current-buffer) abuf)
- (pop-to-buffer-same-window abuf))
- (setq org-agenda-pre-window-conf
- (or wconf org-agenda-pre-window-conf))))
-
-(defun org-agenda-prepare (&optional name)
- (let ((filter-alist (when org-agenda-persistent-filter
- (with-current-buffer
- (get-buffer-create org-agenda-buffer-name)
- `((tag . ,org-agenda-tag-filter)
- (re . ,org-agenda-regexp-filter)
- (effort . ,org-agenda-effort-filter)
- (cat . ,org-agenda-category-filter))))))
- (if (org-agenda-use-sticky-p)
- (progn
- (put 'org-agenda-tag-filter :preset-filter nil)
- (put 'org-agenda-category-filter :preset-filter nil)
- (put 'org-agenda-regexp-filter :preset-filter nil)
- (put 'org-agenda-effort-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)
- (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)
- (put 'org-agenda-effort-filter :preset-filter
- org-agenda-effort-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-agenda-last-prefix-arg current-prefix-arg)
- (setq org-agenda-this-buffer-name org-agenda-buffer-name)
- (and name (not org-agenda-name)
- (setq-local org-agenda-name name)))
- (setq buffer-read-only nil))))
-
-(defvar org-overriding-columns-format)
-(defvar org-local-columns-format)
-(defun org-agenda-finalize ()
- "Finishing touch for the agenda buffer.
-This function is called just before displaying the agenda. If
-you want to add your own functions to the finalization of the
-agenda display, configure `org-agenda-finalize-hook'."
- (unless org-agenda-multi
- (let ((inhibit-read-only t))
- (save-excursion
- (goto-char (point-min))
- (save-excursion
- (while (org-activate-links (point-max))
- (goto-char (match-end 0))))
- (unless (eq org-agenda-remove-tags t)
- (org-agenda-align-tags))
- (unless org-agenda-with-colors
- (remove-text-properties (point-min) (point-max) '(face nil)))
- (when (bound-and-true-p org-overriding-columns-format)
- (setq-local org-local-columns-format
- org-overriding-columns-format))
- (when org-agenda-view-columns-initially
- (org-agenda-columns))
- (when org-agenda-fontify-priorities
- (org-agenda-fontify-priorities))
- (when (and org-agenda-dim-blocked-tasks org-blocker-hook)
- (org-agenda-dim-blocked-tasks))
- (org-agenda-mark-clocking-task)
- (when org-agenda-entry-text-mode
- (org-agenda-entry-text-hide)
- (org-agenda-entry-text-show))
- (when (and (featurep 'org-habit)
- (save-excursion (next-single-property-change (point-min) 'org-habit-p)))
- (org-habit-insert-consistency-graphs))
- (setq org-agenda-type (org-get-at-bol 'org-agenda-type))
- (unless (or (eq org-agenda-show-inherited-tags 'always)
- (and (listp org-agenda-show-inherited-tags)
- (memq org-agenda-type org-agenda-show-inherited-tags))
- (and (eq org-agenda-show-inherited-tags t)
- (or (eq org-agenda-use-tag-inheritance t)
- (and (listp org-agenda-use-tag-inheritance)
- (not (memq org-agenda-type
- org-agenda-use-tag-inheritance))))))
- (let (mrk)
- (save-excursion
- (goto-char (point-min))
- (while (equal (forward-line) 0)
- (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
- (org-get-tags))))))))
- (setq org-agenda-represented-tags nil
- org-agenda-represented-categories nil)
- (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 t))
- (when (get 'org-agenda-tag-filter :preset-filter)
- (org-agenda-filter-apply
- (get 'org-agenda-tag-filter :preset-filter) 'tag t))
- (when org-agenda-category-filter
- (org-agenda-filter-apply org-agenda-category-filter 'category))
- (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))
- (when org-agenda-effort-filter
- (org-agenda-filter-apply org-agenda-effort-filter 'effort))
- (when (get 'org-agenda-effort-filter :preset-filter)
- (org-agenda-filter-apply
- (get 'org-agenda-effort-filter :preset-filter) 'effort))
- (add-hook 'kill-buffer-hook #'org-agenda-reset-markers 'append 'local))
- (run-hooks 'org-agenda-finalize-hook))))
-
-(defun org-agenda-mark-clocking-task ()
- "Mark the current clock entry in the agenda if it is present."
- ;; We need to widen when `org-agenda-finalize' is called from
- ;; `org-agenda-change-all-lines' (e.g. in `org-agenda-clock-in').
- (when (bound-and-true-p 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."
- (mapc (lambda (o)
- (when (eq (overlay-get o 'type) 'org-agenda-clocking)
- (delete-overlay o)))
- (overlays-in (point-min) (point-max))))
-
-(defun org-agenda-fontify-priorities ()
- "Make highest priority lines bold, and lowest italic."
- (interactive)
- (mapc (lambda (o) (when (eq (overlay-get o 'org-type) 'org-priority)
- (delete-overlay o)))
- (overlays-in (point-min) (point-max)))
- (save-excursion
- (let (b e p ov h l)
- (goto-char (point-min))
- (while (re-search-forward org-priority-regexp nil t)
- (setq h (or (get-char-property (point) 'org-priority-highest)
- org-priority-highest)
- l (or (get-char-property (point) 'org-priority-lowest)
- org-priority-lowest)
- p (string-to-char (match-string 2))
- b (match-beginning 1)
- e (if (eq org-agenda-fontify-priorities 'cookies)
- (1+ (match-end 2))
- (point-at-eol))
- ov (make-overlay b e))
- (overlay-put
- ov 'face
- (let ((special-face
- (cond ((org-face-from-face-or-color
- 'priority 'org-priority
- (cdr (assoc p org-priority-faces))))
- ((and (listp org-agenda-fontify-priorities)
- (org-face-from-face-or-color
- 'priority 'org-priority
- (cdr (assoc p org-agenda-fontify-priorities)))))
- ((equal p l) 'italic)
- ((equal p h) 'bold))))
- (if special-face (list special-face 'org-priority) 'org-priority)))
- (overlay-put ov 'org-type 'org-priority)))))
-
-(defvar org-depend-tag-blocked)
-
-(defun org-agenda-dim-blocked-tasks (&optional _invisible)
- "Dim currently blocked TODOs in the agenda display.
-When INVISIBLE is non-nil, hide currently blocked TODO instead of
-dimming them." ;FIXME: The arg isn't used, actually!
- (interactive "P")
- (when (called-interactively-p 'interactive)
- (message "Dim or hide blocked tasks..."))
- (dolist (o (overlays-in (point-min) (point-max)))
- (when (eq (overlay-get o 'face) 'org-agenda-dimmed-todo-face)
- (delete-overlay o)))
- (save-excursion
- (let ((inhibit-read-only t))
- (goto-char (point-min))
- (while (let ((pos (text-property-not-all
- (point) (point-max) 'org-todo-blocked nil)))
- (when pos (goto-char pos)))
- (let* ((invisible
- (eq (org-get-at-bol 'org-todo-blocked) 'invisible))
- (todo-blocked
- (eq (org-get-at-bol 'org-filter-type) 'todo-blocked))
- (ov (make-overlay (if invisible
- (line-end-position 0)
- (line-beginning-position))
- (line-end-position))))
- (when todo-blocked
- (overlay-put ov 'face 'org-agenda-dimmed-todo-face))
- (when invisible
- (org-agenda-filter-hide-line 'todo-blocked)))
- (if (= (point-max) (line-end-position))
- (goto-char (point-max))
- (move-beginning-of-line 2)))))
- (when (called-interactively-p 'interactive)
- (message "Dim or hide blocked tasks...done")))
-
-(defun org-agenda--mark-blocked-entry (entry)
- "If ENTRY is blocked, mark it for fontification or invisibility.
-
-If the header at `org-hd-marker' is blocked according to
-`org-entry-blocked-p', then if `org-agenda-dim-blocked-tasks' is
-'invisible and the header is not blocked by checkboxes, set the
-text property `org-todo-blocked' to `invisible', otherwise set it
-to t."
- (when (get-text-property 0 'todo-state entry)
- (let ((entry-marker (get-text-property 0 'org-hd-marker entry))
- (org-blocked-by-checkboxes nil)
- ;; Necessary so that `org-entry-blocked-p' does not change
- ;; the buffer.
- (org-depend-tag-blocked nil))
- (when entry-marker
- (let ((blocked
- (with-current-buffer (marker-buffer entry-marker)
- (save-excursion
- (goto-char entry-marker)
- (org-entry-blocked-p)))))
- (when blocked
- (let ((really-invisible
- (and (not org-blocked-by-checkboxes)
- (eq org-agenda-dim-blocked-tasks 'invisible))))
- (put-text-property
- 0 (length entry) 'org-todo-blocked
- (if really-invisible 'invisible t)
- entry)
- (put-text-property
- 0 (length entry) 'org-filter-type 'todo-blocked entry)))))))
- entry)
-
-(defvar org-agenda-skip-function nil
- "Function to be called at each match during agenda construction.
-If this function returns nil, the current match should not be skipped.
-Otherwise, the function must return a position from where the search
-should be continued.
-This may also be a Lisp form, it will be evaluated.
-Never set this variable using `setq' or so, because then it will apply
-to all future agenda commands. If you do want a global skipping condition,
-use the option `org-agenda-skip-function-global' instead.
-The correct usage for `org-agenda-skip-function' is to bind it with
-`let' to scope it dynamically into the agenda-constructing command.
-A good way to set it is through options in `org-agenda-custom-commands'.")
-
-(defun org-agenda-skip ()
- "Throw to `:skip' in places that should be skipped.
-Also moves point to the end of the skipped region, so that search can
-continue from there."
- (let ((p (point-at-bol)) to)
- (when (or
- (save-excursion (goto-char p) (looking-at comment-start-skip))
- (and org-agenda-skip-archived-trees (not org-agenda-archives-mode)
- (or (and (get-text-property p :org-archived)
- (org-end-of-subtree t))
- (and (member org-archive-tag org-file-tags)
- (goto-char (point-max)))))
- (and org-agenda-skip-comment-trees
- (get-text-property p :org-comment)
- (org-end-of-subtree t))
- (and (setq to (or (org-agenda-skip-eval org-agenda-skip-function-global)
- (org-agenda-skip-eval org-agenda-skip-function)))
- (goto-char to))
- (org-in-src-block-p t))
- (throw :skip t))))
-
-(defun org-agenda-skip-eval (form)
- "If FORM is a function or a list, call (or eval) it and return the result.
-`save-excursion' and `save-match-data' are wrapped around the call, so point
-and match data are returned to the previous state no matter what these
-functions do."
- (let (fp)
- (and form
- (or (setq fp (functionp form))
- (consp form))
- (save-excursion
- (save-match-data
- (if fp
- (funcall form)
- (eval form t)))))))
-
-(defvar org-agenda-markers nil
- "List of all currently active markers created by `org-agenda'.")
-(defvar org-agenda-last-marker-time (float-time)
- "Creation time of the last agenda marker.")
-
-(defun org-agenda-new-marker (&optional pos)
- "Return a new agenda marker.
-Marker is at point, or at POS if non-nil. 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)) t)))
- (setq org-agenda-last-marker-time (float-time))
- (if org-agenda-buffer
- (with-current-buffer org-agenda-buffer
- (push m org-agenda-markers))
- (push m org-agenda-markers))
- m))
-
-(defun org-agenda-reset-markers ()
- "Reset markers created by `org-agenda'."
- (while org-agenda-markers
- (move-marker (pop org-agenda-markers) nil)))
-
-(defun org-agenda-save-markers-for-cut-and-paste (beg end)
- "Save relative positions of markers in region.
-This check for agenda markers in all agenda buffers currently active."
- (dolist (buf (buffer-list))
- (with-current-buffer buf
- (when (eq major-mode 'org-agenda-mode)
- (mapc (lambda (m) (org-check-and-save-marker m beg end))
- org-agenda-markers)))))
-
-;;; Entry text mode
-
-(defun org-agenda-entry-text-show-here ()
- "Add some text from the entry as context to the current line."
- (let (m txt o)
- (setq m (org-get-at-bol 'org-hd-marker))
- (unless (marker-buffer m)
- (error "No marker points to an entry here"))
- (setq txt (concat "\n" (org-no-properties
- (org-agenda-get-some-entry-text
- m org-agenda-entry-text-maxlines
- org-agenda-entry-text-leaders))))
- (when (string-match "\\S-" txt)
- (setq o (make-overlay (point-at-bol) (point-at-eol)))
- (overlay-put o 'evaporate t)
- (overlay-put o 'org-overlay-type 'agenda-entry-content)
- (overlay-put o 'after-string txt))))
-
-(defun org-agenda-entry-text-show ()
- "Add entry context for all agenda lines."
- (interactive)
- (save-excursion
- (goto-char (point-max))
- (beginning-of-line 1)
- (while (not (bobp))
- (when (org-get-at-bol 'org-hd-marker)
- (org-agenda-entry-text-show-here))
- (beginning-of-line 0))))
-
-(defun org-agenda-entry-text-hide ()
- "Remove any shown entry context."
- (mapc (lambda (o)
- (when (eq (overlay-get o 'org-overlay-type)
- 'agenda-entry-content)
- (delete-overlay o)))
- (overlays-in (point-min) (point-max))))
-
-(defun org-agenda-get-day-face (date)
- "Return the face DATE should be displayed with."
- (cond ((and (functionp org-agenda-day-face-function)
- (funcall org-agenda-day-face-function date)))
- ((and (org-agenda-today-p date)
- (memq (calendar-day-of-week date) org-agenda-weekend-days))
- 'org-agenda-date-weekend-today)
- ((org-agenda-today-p date) 'org-agenda-date-today)
- ((memq (calendar-day-of-week date) org-agenda-weekend-days)
- 'org-agenda-date-weekend)
- (t 'org-agenda-date)))
-
-(defvar org-agenda-show-log-scoped)
-
-;;; Agenda Daily/Weekly
-
-(defvar org-agenda-start-day nil ; dynamically scoped parameter
- "Start day for the agenda view.
-Custom commands can set this variable in the options section.
-This is usually a string like \"2007-11-01\", \"+2d\" or any other
-input allowed when reading a date through the Org calendar.
-See the docstring of `org-read-date' for details.")
-(defvar org-starting-day nil) ; local variable in the agenda buffer
-(defvar org-arg-loc nil) ; local variable
-
-;;;###autoload
-(defun org-agenda-list (&optional arg start-day span with-hour)
- "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 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'.
-
-When WITH-HOUR is non-nil, only include scheduled and deadline
-items if they have an hour specification like [h]h:mm."
- (interactive "P")
- (when 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)))
- (when (and (integerp arg) (> arg 0))
- (setq span arg arg nil))
- (when (numberp span)
- (unless (< 0 span)
- (user-error "Agenda creation impossible for this span(=%d days)" span)))
- (catch 'exit
- (setq org-agenda-buffer-name
- (org-agenda--get-buffer-name
- (and org-agenda-sticky
- (cond ((and org-keys (stringp org-match))
- (format "*Org Agenda(%s:%s)*" org-keys org-match))
- (org-keys
- (format "*Org Agenda(%s)*" org-keys))
- (t "*Org Agenda(a)*")))))
- (org-agenda-prepare "Day/Week")
- (setq start-day (or start-day org-agenda-start-day))
- (when (stringp start-day)
- ;; Convert to an absolute day number
- (setq start-day (time-to-days (org-read-date nil t start-day))))
- (org-compile-prefix-format 'agenda)
- (org-set-sorting-strategy 'agenda)
- (let* ((span (org-agenda-ndays-to-span (or span org-agenda-span)))
- (today (org-today))
- (sd (or start-day today))
- (ndays (org-agenda-span-to-ndays span sd))
- (org-agenda-start-on-weekday
- (and (or (eq ndays 7) (eq ndays 14))
- org-agenda-start-on-weekday))
- (thefiles (org-agenda-files nil 'ifmode))
- (files thefiles)
- (start (if (or (null org-agenda-start-on-weekday)
- (< ndays 7))
- sd
- (let* ((nt (calendar-day-of-week
- (calendar-gregorian-from-absolute sd)))
- (n1 org-agenda-start-on-weekday)
- (d (- nt n1)))
- (- sd (+ (if (< d 0) 7 0) d)))))
- (day-numbers (list start))
- (day-cnt 0)
- (inhibit-redisplay (not debug-on-error))
- (org-agenda-show-log-scoped org-agenda-show-log)
- s rtn rtnall file date d start-pos end-pos todayp ;; e
- clocktable-start clocktable-end) ;; filter
- (setq org-agenda-redo-command
- (list 'org-agenda-list (list 'quote arg) start-day (list 'quote span) with-hour))
- (dotimes (_ (1- ndays))
- (push (1+ (car day-numbers)) day-numbers))
- (setq day-numbers (nreverse day-numbers))
- (setq clocktable-start (car day-numbers)
- clocktable-end (1+ (or (org-last day-numbers) 0)))
- (setq-local org-starting-day (car day-numbers))
- (setq-local org-arg-loc arg)
- (setq-local org-agenda-current-span (org-agenda-ndays-to-span span))
- (unless org-agenda-compact-blocks
- (let* ((d1 (car day-numbers))
- (d2 (org-last day-numbers))
- (w1 (org-days-to-iso-week d1))
- (w2 (org-days-to-iso-week d2)))
- (setq s (point))
- (org-agenda--insert-overriding-header
- (concat (org-agenda-span-name span)
- "-agenda"
- (cond ((<= 350 (- d2 d1)) "")
- ((= w1 w2) (format " (W%02d)" w1))
- (t (format " (W%02d-W%02d)" w1 w2)))
- ":\n")))
- ;; Add properties if we actually inserted a header.
- (when (> (point) s)
- (add-text-properties s (1- (point))
- (list 'face 'org-agenda-structure
- 'org-date-line t))
- (org-agenda-mark-header-line s)))
- (while (setq d (pop day-numbers))
- (setq date (calendar-gregorian-from-absolute d)
- s (point))
- (if (or (setq todayp (= d today))
- (and (not start-pos) (= d sd)))
- (setq start-pos (point))
- (when (and start-pos (not end-pos))
- (setq end-pos (point))))
- (setq files thefiles
- rtnall nil)
- (while (setq file (pop files))
- (catch 'nextfile
- (org-check-agenda-file file)
- (let ((org-agenda-entry-types org-agenda-entry-types))
- ;; Starred types override non-starred equivalents
- (when (member :deadline* org-agenda-entry-types)
- (setq org-agenda-entry-types
- (delq :deadline org-agenda-entry-types)))
- (when (member :scheduled* org-agenda-entry-types)
- (setq org-agenda-entry-types
- (delq :scheduled org-agenda-entry-types)))
- ;; Honor with-hour
- (when with-hour
- (when (member :deadline org-agenda-entry-types)
- (setq org-agenda-entry-types
- (delq :deadline org-agenda-entry-types))
- (push :deadline* org-agenda-entry-types))
- (when (member :scheduled org-agenda-entry-types)
- (setq org-agenda-entry-types
- (delq :scheduled org-agenda-entry-types))
- (push :scheduled* org-agenda-entry-types)))
- (unless org-agenda-include-deadlines
- (setq org-agenda-entry-types
- (delq :deadline* (delq :deadline org-agenda-entry-types))))
- (cond
- ((memq org-agenda-show-log-scoped '(only clockcheck))
- (setq rtn (org-agenda-get-day-entries
- file date :closed)))
- (org-agenda-show-log-scoped
- (setq rtn (apply #'org-agenda-get-day-entries
- file date
- (append '(:closed) org-agenda-entry-types))))
- (t
- (setq rtn (apply #'org-agenda-get-day-entries
- file date
- org-agenda-entry-types)))))
- (setq rtnall (append rtnall rtn)))) ;; all entries
- (when org-agenda-include-diary
- (let ((org-agenda-search-headline-for-time t))
- (require 'diary-lib)
- (setq rtn (org-get-entries-from-diary date))
- (setq rtnall (append rtnall rtn))))
- (when (or rtnall org-agenda-show-all-dates)
- (setq day-cnt (1+ day-cnt))
- (insert
- (if (stringp org-agenda-format-date)
- (format-time-string org-agenda-format-date
- (org-time-from-absolute date))
- (funcall org-agenda-format-date date))
- "\n")
- (put-text-property s (1- (point)) 'face
- (org-agenda-get-day-face date))
- (put-text-property s (1- (point)) 'org-date-line t)
- (put-text-property s (1- (point)) 'org-agenda-date-header t)
- (put-text-property s (1- (point)) 'org-day-cnt day-cnt)
- (when todayp
- (put-text-property s (1- (point)) 'org-today t))
- (setq rtnall
- (org-agenda-add-time-grid-maybe rtnall ndays todayp))
- (when rtnall (insert ;; all entries
- (org-agenda-finalize-entries rtnall 'agenda)
- "\n"))
- (put-text-property s (1- (point)) 'day d)
- (put-text-property s (1- (point)) 'org-day-cnt day-cnt)))
- (when (and org-agenda-clockreport-mode clocktable-start)
- (let ((org-agenda-files (org-agenda-files nil 'ifmode))
- ;; the above line is to ensure the restricted range!
- (p (copy-sequence org-agenda-clockreport-parameter-plist))
- tbl)
- (setq p (org-plist-delete p :block))
- (setq p (plist-put p :tstart clocktable-start))
- (setq p (plist-put p :tend clocktable-end))
- (setq p (plist-put p :scope 'agenda))
- (setq tbl (apply #'org-clock-get-clocktable p))
- (insert tbl)))
- (goto-char (point-min))
- (or org-agenda-multi (org-agenda-fit-window-to-buffer))
- (unless (or (not (get-buffer-window org-agenda-buffer-name))
- (and (pos-visible-in-window-p (point-min))
- (pos-visible-in-window-p (point-max))))
- (goto-char (1- (point-max)))
- (recenter -1)
- (when (not (pos-visible-in-window-p (or start-pos 1)))
- (goto-char (or start-pos 1))
- (recenter 1)))
- (goto-char (or start-pos 1))
- (add-text-properties (point-min) (point-max)
- `(org-agenda-type agenda
- org-last-args (,arg ,start-day ,span)
- org-redo-cmd ,org-agenda-redo-command
- org-series-cmd ,org-cmd))
- (when (eq org-agenda-show-log-scoped 'clockcheck)
- (org-agenda-show-clocking-issues))
- (org-agenda-finalize)
- (setq buffer-read-only t)
- (message ""))))
-
-(defun org-agenda-ndays-to-span (n)
- "Return a span symbol for a span of N days, or N if none matches."
- (cond ((symbolp n) n)
- ((= n 1) 'day)
- ((= n 7) 'week)
- ((= n 14) 'fortnight)
- (t n)))
-
-(defun org-agenda-span-to-ndays (span &optional start-day)
- "Return ndays from SPAN, possibly starting at START-DAY.
-START-DAY is an absolute time value."
- (cond ((numberp span) span)
- ((eq span 'day) 1)
- ((eq span 'week) 7)
- ((eq span 'fortnight) 14)
- ((eq span 'month)
- (let ((date (calendar-gregorian-from-absolute start-day)))
- (calendar-last-day-of-month (car date) (cl-caddr date))))
- ((eq span 'year)
- (let ((date (calendar-gregorian-from-absolute start-day)))
- (if (calendar-leap-year-p (cl-caddr date)) 366 365)))))
-
-(defun org-agenda-span-name (span)
- "Return a SPAN name."
- (if (null span)
- ""
- (if (symbolp span)
- (capitalize (symbol-name span))
- (format "%d days" span))))
-
-;;; Agenda word search
-
-(defvar org-agenda-search-history nil)
-
-(defvar org-search-syntax-table nil
- "Special syntax table for Org search.
-In this table, we have single quotes not as word constituents, to
-that when \"+Ameli\" is searched as a work, it will also match \"Ameli's\"")
-
-(defvar org-mode-syntax-table) ; From org.el
-(defun org-search-syntax-table ()
- (unless org-search-syntax-table
- (setq org-search-syntax-table (copy-syntax-table org-mode-syntax-table))
- (modify-syntax-entry ?' "." org-search-syntax-table)
- (modify-syntax-entry ?` "." org-search-syntax-table))
- org-search-syntax-table)
-
-(defvar org-agenda-last-search-view-search-was-boolean nil)
-
-;;;###autoload
-(defun org-search-view (&optional todo-only string edit-at)
- "Show all entries that contain a phrase or words or regular expressions.
-
-With optional prefix argument TODO-ONLY, only consider entries that are
-TODO entries. The argument STRING can be used to pass a default search
-string into this function. If EDIT-AT is non-nil, it means that the
-user should get a chance to edit this string, with cursor at position
-EDIT-AT.
-
-The search string can be viewed either as a phrase that should be found as
-is, or it can be broken into a number of snippets, each of which must match
-in a Boolean way to select an entry. The default depends on the variable
-`org-agenda-search-view-always-boolean'.
-Even if this is turned off (the default) you can always switch to
-Boolean search dynamically by preceding the first word with \"+\" or \"-\".
-
-The default is a direct search of the whole phrase, where each space in
-the search string can expand to an arbitrary amount of whitespace,
-including newlines.
-
-If using a Boolean search, the search string is split on whitespace and
-each snippet is searched separately, with logical AND to select an entry.
-Words prefixed with a minus must *not* occur in the entry. Words without
-a prefix or prefixed with a plus must occur in the entry. Matching is
-case-insensitive. Words are enclosed by word delimiters (i.e. they must
-match whole words, not parts of a word) if
-`org-agenda-search-view-force-full-words' is set (default is nil).
-
-Boolean search snippets enclosed by curly braces are interpreted as
-regular expressions that must or (when preceded with \"-\") must not
-match in the entry. Snippets enclosed into double quotes will be taken
-as a whole, to include whitespace.
-
-- If the search string starts with an asterisk, search only in headlines.
-- If (possibly after the leading star) the search string starts with an
- exclamation mark, this also means to look at TODO entries only, an effect
- that can also be achieved with a prefix argument.
-- If (possibly after star and exclamation mark) the search string starts
- with a colon, this will mean that the (non-regexp) snippets of the
- Boolean search must match as full words.
-
-This command searches the agenda files, and in addition the files
-listed in `org-agenda-text-search-extra-files' unless a restriction lock
-is active."
- (interactive "P")
- (when org-agenda-overriding-arguments
- (setq todo-only (car org-agenda-overriding-arguments)
- string (nth 1 org-agenda-overriding-arguments)
- edit-at (nth 2 org-agenda-overriding-arguments)))
- (let* ((props (list 'face nil
- 'done-face 'org-agenda-done
- 'org-not-done-regexp org-not-done-regexp
- 'org-todo-regexp org-todo-regexp
- 'org-complex-heading-regexp org-complex-heading-regexp
- 'mouse-face 'highlight
- 'help-echo "mouse-2 or RET jump to location"))
- (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 inherited-tags
- marker category level tags c neg re boolean
- ee txt beg end words regexps+ regexps- hdl-only buffer beg1 str)
- (unless (and (not edit-at)
- (stringp string)
- (string-match "\\S-" string))
- (setq string (read-string
- (if org-agenda-search-view-always-boolean
- "[+-]Word/{Regexp} ...: "
- "Phrase or [+-]Word/{Regexp} ...: ")
- (cond
- ((integerp edit-at) (cons string edit-at))
- (edit-at string))
- 'org-agenda-search-history)))
- (catch 'exit
- (setq org-agenda-buffer-name
- (org-agenda--get-buffer-name
- (and org-agenda-sticky
- (if (stringp string)
- (format "*Org Agenda(%s:%s)*"
- (or org-keys (or (and todo-only "S") "s"))
- string)
- (format "*Org Agenda(%s)*"
- (or (and todo-only "S") "s"))))))
- (org-agenda-prepare "SEARCH")
- (org-compile-prefix-format 'search)
- (org-set-sorting-strategy 'search)
- (setq org-agenda-redo-command
- (list 'org-search-view (if todo-only t nil)
- (list 'if 'current-prefix-arg nil string)))
- (setq org-agenda-query-string string)
- (if (equal (string-to-char string) ?*)
- (setq hdl-only t
- words (substring string 1))
- (setq words string))
- (when (equal (string-to-char words) ?!)
- (setq todo-only t
- words (substring words 1)))
- (when (equal (string-to-char words) ?:)
- (setq full-words t
- words (substring words 1)))
- (when (or org-agenda-search-view-always-boolean
- (member (string-to-char words) '(?- ?+ ?\{)))
- (setq boolean t))
- (setq words (split-string words))
- (let (www w)
- (while (setq w (pop words))
- (while (and (string-match "\\\\\\'" w) words)
- (setq w (concat (substring w 0 -1) " " (pop words))))
- (push w www))
- (setq words (nreverse www) www nil)
- (while (setq w (pop words))
- (when (and (string-match "\\`[-+]?{" w)
- (not (string-match "}\\'" w)))
- (while (and words (not (string-match "}\\'" (car words))))
- (setq w (concat w " " (pop words))))
- (setq w (concat w " " (pop words))))
- (push w www))
- (setq words (nreverse www)))
- (setq org-agenda-last-search-view-search-was-boolean boolean)
- (when boolean
- (let (wds w)
- (while (setq w (pop words))
- (when (or (equal (substring w 0 1) "\"")
- (and (> (length w) 1)
- (member (substring w 0 1) '("+" "-"))
- (equal (substring w 1 2) "\"")))
- (while (and words (not (equal (substring w -1) "\"")))
- (setq w (concat w " " (pop words)))))
- (and (string-match "\\`\\([-+]?\\)\"" w)
- (setq w (replace-match "\\1" nil nil w)))
- (and (equal (substring w -1) "\"") (setq w (substring w 0 -1)))
- (push w wds))
- (setq words (nreverse wds))))
- (if boolean
- (mapc (lambda (w)
- (setq c (string-to-char w))
- (if (equal c ?-)
- (setq neg t w (substring w 1))
- (if (equal c ?+)
- (setq neg nil w (substring w 1))
- (setq neg nil)))
- (if (string-match "\\`{.*}\\'" w)
- (setq re (substring w 1 -1))
- (if full-words
- (setq re (concat "\\<" (regexp-quote (downcase w)) "\\>"))
- (setq re (regexp-quote (downcase w)))))
- (if neg (push re regexps-) (push re regexps+)))
- words)
- (push (mapconcat #'regexp-quote words "\\s-+")
- regexps+))
- (setq regexps+ (sort regexps+ (lambda (a b) (> (length a) (length b)))))
- (if (not regexps+)
- (setq regexp org-outline-regexp-bol)
- (setq regexp (pop regexps+))
- (when hdl-only (setq regexp (concat org-outline-regexp-bol ".*?"
- regexp))))
- (setq files (org-agenda-files nil 'ifmode))
- ;; Add `org-agenda-text-search-extra-files' unless there is some
- ;; restriction.
- (when (eq (car org-agenda-text-search-extra-files) 'agenda-archives)
- (pop org-agenda-text-search-extra-files)
- (unless (get 'org-agenda-files 'org-restrict)
- (setq files (org-add-archive-files files))))
- ;; Uniquify files. However, let `org-check-agenda-file' handle
- ;; non-existent ones.
- (setq files (cl-remove-duplicates
- (append files org-agenda-text-search-extra-files)
- :test (lambda (a b)
- (and (file-exists-p a)
- (file-exists-p b)
- (file-equal-p a b))))
- rtnall nil)
- (while (setq file (pop files))
- (setq ee nil)
- (catch 'nextfile
- (org-check-agenda-file file)
- (setq buffer (if (file-exists-p file)
- (org-get-agenda-file-buffer file)
- (error "No such file %s" file)))
- (unless buffer
- ;; If file does not exist, make sure an error message is sent
- (setq rtn (list (format "ORG-AGENDA-ERROR: No such org-file %s"
- file))))
- (with-current-buffer buffer
- (with-syntax-table (org-search-syntax-table)
- (unless (derived-mode-p 'org-mode)
- (error "Agenda file %s is not in Org mode" file))
- (let ((case-fold-search t))
- (save-excursion
- (save-restriction
- (if (eq buffer org-agenda-restrict)
- (narrow-to-region org-agenda-restrict-begin
- org-agenda-restrict-end)
- (widen))
- (goto-char (point-min))
- (unless (or (org-at-heading-p)
- (outline-next-heading))
- (throw 'nextfile t))
- (goto-char (max (point-min) (1- (point))))
- (while (re-search-forward regexp nil t)
- (org-back-to-heading t)
- (while (and (not (zerop org-agenda-search-view-max-outline-level))
- (> (org-reduced-level (org-outline-level))
- org-agenda-search-view-max-outline-level)
- (forward-line -1)
- (org-back-to-heading t)))
- (skip-chars-forward "* ")
- (setq beg (point-at-bol)
- beg1 (point)
- end (progn
- (outline-next-heading)
- (while (and (not (zerop org-agenda-search-view-max-outline-level))
- (> (org-reduced-level (org-outline-level))
- org-agenda-search-view-max-outline-level)
- (forward-line 1)
- (outline-next-heading)))
- (point)))
-
- (catch :skip
- (goto-char beg)
- (org-agenda-skip)
- (setq str (buffer-substring-no-properties
- (point-at-bol)
- (if hdl-only (point-at-eol) end)))
- (mapc (lambda (wr) (when (string-match wr str)
- (goto-char (1- end))
- (throw :skip t)))
- regexps-)
- (mapc (lambda (wr) (unless (string-match wr str)
- (goto-char (1- end))
- (throw :skip t)))
- (if todo-only
- (cons (concat "^\\*+[ \t]+"
- org-not-done-regexp)
- regexps+)
- regexps+))
- (goto-char beg)
- (setq marker (org-agenda-new-marker (point))
- category (org-get-category)
- level (make-string (org-reduced-level (org-outline-level)) ? )
- inherited-tags
- (or (eq org-agenda-show-inherited-tags 'always)
- (and (listp org-agenda-show-inherited-tags)
- (memq 'todo org-agenda-show-inherited-tags))
- (and (eq org-agenda-show-inherited-tags t)
- (or (eq org-agenda-use-tag-inheritance t)
- (memq 'todo org-agenda-use-tag-inheritance))))
- tags (org-get-tags nil (not inherited-tags))
- txt (org-agenda-format-item
- ""
- (buffer-substring-no-properties
- beg1 (point-at-eol))
- level category tags t))
- (org-add-props txt props
- 'org-marker marker 'org-hd-marker marker
- 'org-todo-regexp org-todo-regexp
- 'level level
- 'org-complex-heading-regexp org-complex-heading-regexp
- 'priority 1000
- 'type "search")
- (push txt ee)
- (goto-char (1- end))))))))))
- (setq rtn (nreverse ee))
- (setq rtnall (append rtnall rtn)))
- (org-agenda--insert-overriding-header
- (with-temp-buffer
- (insert "Search words: ")
- (add-text-properties (point-min) (1- (point))
- (list 'face 'org-agenda-structure))
- (setq pos (point))
- (insert string "\n")
- (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure-filter))
- (setq pos (point))
- (unless org-agenda-multi
- (insert (substitute-command-keys "\\<org-agenda-mode-map>\
-Press `\\[org-agenda-manipulate-query-add]', \
-`\\[org-agenda-manipulate-query-subtract]' to add/sub word, \
-`\\[org-agenda-manipulate-query-add-re]', \
-`\\[org-agenda-manipulate-query-subtract-re]' to add/sub regexp, \
-`\\[universal-argument] \\[org-agenda-redo]' for a fresh search\n"))
- (add-text-properties pos (1- (point))
- (list 'face 'org-agenda-structure-secondary)))
- (buffer-string)))
- (org-agenda-mark-header-line (point-min))
- (when rtnall
- (insert (org-agenda-finalize-entries rtnall 'search) "\n"))
- (goto-char (point-min))
- (or org-agenda-multi (org-agenda-fit-window-to-buffer))
- (add-text-properties (point-min) (point-max)
- `(org-agenda-type search
- org-last-args (,todo-only ,string ,edit-at)
- org-redo-cmd ,org-agenda-redo-command
- org-series-cmd ,org-cmd))
- (org-agenda-finalize)
- (setq buffer-read-only t))))
-
-;;; Agenda TODO list
-
-(defun org-agenda-propertize-selected-todo-keywords (keywords)
- "Use `org-todo-keyword-faces' for the selected todo KEYWORDS."
- (concat
- (if (or (equal keywords "ALL") (not keywords))
- (propertize "ALL" 'face 'org-agenda-structure-filter)
- (mapconcat
- (lambda (kw)
- (propertize kw 'face (list (org-get-todo-face kw) 'org-agenda-structure)))
- (org-split-string keywords "|")
- "|"))
- "\n"))
-
-(defvar org-select-this-todo-keyword nil)
-(defvar org-last-arg nil)
-
-(defvar crm-separator)
-
-;;;###autoload
-(defun org-todo-list (&optional arg)
- "Show all (not done) TODO entries from all agenda file in a single list.
-The prefix arg can be used to select a specific TODO keyword and limit
-the list to these. When using `\\[universal-argument]', you will be prompted
-for a keyword. A numeric prefix directly selects the Nth keyword in
-`org-todo-keywords-1'."
- (interactive "P")
- (when org-agenda-overriding-arguments
- (setq arg org-agenda-overriding-arguments))
- (when (and (stringp arg) (not (string-match "\\S-" arg))) (setq arg nil))
- (let* ((today (org-today))
- (date (calendar-gregorian-from-absolute today))
- (completion-ignore-case t)
- kwds org-select-this-todo-keyword rtn rtnall files file pos)
- (catch 'exit
- (setq org-agenda-buffer-name
- (org-agenda--get-buffer-name
- (and org-agenda-sticky
- (if (stringp org-select-this-todo-keyword)
- (format "*Org Agenda(%s:%s)*" (or org-keys "t")
- org-select-this-todo-keyword)
- (format "*Org Agenda(%s)*" (or org-keys "t"))))))
- (org-agenda-prepare "TODO")
- (setq kwds org-todo-keywords-for-agenda
- org-select-this-todo-keyword (if (stringp arg) arg
- (and (integerp arg)
- (> arg 0)
- (nth (1- arg) kwds))))
- (when (equal arg '(4))
- (setq org-select-this-todo-keyword
- (mapconcat #'identity
- (let ((crm-separator "|"))
- (completing-read-multiple
- "Keyword (or KWD1|KWD2|...): "
- (mapcar #'list kwds) nil nil))
- "|")))
- (and (equal 0 arg) (setq org-select-this-todo-keyword nil))
- (org-compile-prefix-format 'todo)
- (org-set-sorting-strategy 'todo)
- (setq org-agenda-redo-command
- `(org-todo-list (or (and (numberp current-prefix-arg)
- current-prefix-arg)
- ,org-select-this-todo-keyword
- current-prefix-arg ,arg)))
- (setq files (org-agenda-files nil 'ifmode)
- rtnall nil)
- (while (setq file (pop files))
- (catch 'nextfile
- (org-check-agenda-file file)
- (setq rtn (org-agenda-get-day-entries file date :todo))
- (setq rtnall (append rtnall rtn))))
- (org-agenda--insert-overriding-header
- (with-temp-buffer
- (insert "Global list of TODO items of type: ")
- (add-text-properties (point-min) (1- (point))
- (list 'face 'org-agenda-structure
- 'short-heading
- (concat "ToDo: "
- (or org-select-this-todo-keyword "ALL"))))
- (org-agenda-mark-header-line (point-min))
- (insert (org-agenda-propertize-selected-todo-keywords
- org-select-this-todo-keyword))
- (setq pos (point))
- (unless org-agenda-multi
- (insert (substitute-command-keys "Press \
-\\<org-agenda-mode-map>`N \\[org-agenda-redo]' (e.g. `0 \\[org-agenda-redo]') \
-to search again: (0)[ALL]"))
- (let ((n 0))
- (dolist (k kwds)
- (let ((s (format "(%d)%s" (cl-incf n) k)))
- (when (> (+ (current-column) (string-width s) 1) (window-width))
- (insert "\n "))
- (insert " " s))))
- (insert "\n"))
- (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure-secondary))
- (buffer-string)))
- (org-agenda-mark-header-line (point-min))
- (when rtnall
- (insert (org-agenda-finalize-entries rtnall 'todo) "\n"))
- (goto-char (point-min))
- (or org-agenda-multi (org-agenda-fit-window-to-buffer))
- (add-text-properties (point-min) (point-max)
- `(org-agenda-type todo
- org-last-args ,arg
- org-redo-cmd ,org-agenda-redo-command
- org-series-cmd ,org-cmd))
- (org-agenda-finalize)
- (setq buffer-read-only t))))
-
-;;; Agenda tags match
-
-;;;###autoload
-(defun org-tags-view (&optional todo-only match)
- "Show all headlines for all `org-agenda-files' matching a TAGS criterion.
-The prefix arg TODO-ONLY limits the search to TODO entries."
- (interactive "P")
- (when org-agenda-overriding-arguments
- (setq todo-only (car org-agenda-overriding-arguments)
- match (nth 1 org-agenda-overriding-arguments)))
- (let* ((org-tags-match-list-sublevels
- org-tags-match-list-sublevels)
- (completion-ignore-case t)
- (org--matcher-tags-todo-only todo-only)
- rtn rtnall files file pos matcher
- buffer)
- (when (and (stringp match) (not (string-match "\\S-" match)))
- (setq match nil))
- (catch 'exit
- (setq org-agenda-buffer-name
- (org-agenda--get-buffer-name
- (and org-agenda-sticky
- (if (stringp match)
- (format "*Org Agenda(%s:%s)*"
- (or org-keys (or (and todo-only "M") "m"))
- match)
- (format "*Org Agenda(%s)*"
- (or (and todo-only "M") "m"))))))
- (setq matcher (org-make-tags-matcher match))
- ;; Prepare agendas (and `org-tag-alist-for-agenda') before
- ;; expanding tags within `org-make-tags-matcher'
- (org-agenda-prepare (concat "TAGS " match))
- (setq match (car matcher)
- matcher (cdr matcher))
- (org-compile-prefix-format 'tags)
- (org-set-sorting-strategy 'tags)
- (setq org-agenda-query-string match)
- (setq org-agenda-redo-command
- (list 'org-tags-view
- `(quote ,org--matcher-tags-todo-only)
- `(if current-prefix-arg nil ,org-agenda-query-string)))
- (setq files (org-agenda-files nil 'ifmode)
- rtnall nil)
- (while (setq file (pop files))
- (catch 'nextfile
- (org-check-agenda-file file)
- (setq buffer (if (file-exists-p file)
- (org-get-agenda-file-buffer file)
- (error "No such file %s" file)))
- (if (not buffer)
- ;; If file does not exist, error message to agenda
- (setq rtn (list
- (format "ORG-AGENDA-ERROR: No such org-file %s" file))
- rtnall (append rtnall rtn))
- (with-current-buffer buffer
- (unless (derived-mode-p 'org-mode)
- (error "Agenda file %s is not in Org mode" file))
- (save-excursion
- (save-restriction
- (if (eq buffer org-agenda-restrict)
- (narrow-to-region org-agenda-restrict-begin
- org-agenda-restrict-end)
- (widen))
- (setq rtn (org-scan-tags 'agenda
- matcher
- org--matcher-tags-todo-only))
- (setq rtnall (append rtnall rtn))))))))
- (org-agenda--insert-overriding-header
- (with-temp-buffer
- (insert "Headlines with TAGS match: ")
- (add-text-properties (point-min) (1- (point))
- (list 'face 'org-agenda-structure
- 'short-heading
- (concat "Match: " match)))
- (setq pos (point))
- (insert match "\n")
- (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure-filter))
- (setq pos (point))
- (unless org-agenda-multi
- (insert (substitute-command-keys
- "Press \
-\\<org-agenda-mode-map>`\\[universal-argument] \\[org-agenda-redo]' \
-to search again\n")))
- (add-text-properties pos (1- (point))
- (list 'face 'org-agenda-structure-secondary))
- (buffer-string)))
- (org-agenda-mark-header-line (point-min))
- (when rtnall
- (insert (org-agenda-finalize-entries rtnall 'tags) "\n"))
- (goto-char (point-min))
- (or org-agenda-multi (org-agenda-fit-window-to-buffer))
- (add-text-properties
- (point-min) (point-max)
- `(org-agenda-type tags
- org-last-args (,org--matcher-tags-todo-only ,match)
- org-redo-cmd ,org-agenda-redo-command
- org-series-cmd ,org-cmd))
- (org-agenda-finalize)
- (setq buffer-read-only t))))
-
-;;; Agenda Finding stuck projects
-
-(defvar org-agenda-skip-regexp nil
- "Regular expression used in skipping subtrees for the agenda.
-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 set during agenda, todo and tags searches it replaces the header.
-If an empty string, no header will be inserted. If any other
-string, it will be inserted as a header. If a function, insert
-the string returned by the function as a header. If nil, a
-header will be generated automatically according to the command.
-This variable should not be set directly, but custom commands can
-bind it in the options section.")
-
-(defun org-agenda-skip-entry-if (&rest conditions)
- "Skip entry if any of CONDITIONS is true.
-See `org-agenda-skip-if' for details."
- (org-agenda-skip-if nil conditions))
-
-(defun org-agenda-skip-subtree-if (&rest conditions)
- "Skip subtree if any of CONDITIONS is true.
-See `org-agenda-skip-if' for details."
- (org-agenda-skip-if t conditions))
-
-(defun org-agenda-skip-if (subtree conditions)
- "Check current entity for CONDITIONS.
-If SUBTREE is non-nil, the entire subtree is checked. Otherwise, only
-the entry (i.e. the text before the next heading) is checked.
-
-CONDITIONS is a list of symbols, boolean OR is used to combine the results
-from different tests. Valid conditions are:
-
-scheduled Check if there is a scheduled cookie
-notscheduled Check if there is no scheduled cookie
-deadline Check if there is a deadline
-notdeadline Check if there is no deadline
-timestamp Check if there is a timestamp (also deadline or scheduled)
-nottimestamp Check if there is no timestamp (also deadline or scheduled)
-regexp Check if regexp matches
-notregexp Check if regexp does not match.
-todo Check if TODO keyword matches
-nottodo Check if TODO keyword does not match
-
-The regexp is taken from the conditions list, it must come right after
-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\"))
-
-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)
-
-would skip entries that haven't been marked with any of \"DONE\"
-keywords. Possible classes are: `todo', `done', `any'.
-
-If any of these conditions is met, this function returns the end point of
-the entity, causing the search to continue from there. This is a function
-that can be put into `org-agenda-skip-function' for the duration of a command."
- (org-back-to-heading t)
- (let* (;; (beg (point))
- (end (if subtree (save-excursion (org-end-of-subtree t) (point))
- (org-entry-end-position)))
- (planning-end (if subtree end (line-end-position 2)))
- m)
- (and
- (or (and (memq 'scheduled conditions)
- (re-search-forward org-scheduled-time-regexp planning-end t))
- (and (memq 'notscheduled conditions)
- (not
- (save-excursion
- (re-search-forward org-scheduled-time-regexp planning-end t))))
- (and (memq 'deadline conditions)
- (re-search-forward org-deadline-time-regexp planning-end t))
- (and (memq 'notdeadline conditions)
- (not
- (save-excursion
- (re-search-forward org-deadline-time-regexp planning-end t))))
- (and (memq 'timestamp conditions)
- (re-search-forward org-ts-regexp end t))
- (and (memq 'nottimestamp conditions)
- (not (save-excursion (re-search-forward org-ts-regexp end t))))
- (and (setq m (memq 'regexp conditions))
- (stringp (nth 1 m))
- (re-search-forward (nth 1 m) end t))
- (and (setq m (memq 'notregexp conditions))
- (stringp (nth 1 m))
- (not (save-excursion (re-search-forward (nth 1 m) end t))))
- (and (or
- (setq m (memq 'nottodo conditions))
- (setq m (memq 'todo-unblocked conditions))
- (setq m (memq 'nottodo-unblocked conditions))
- (setq m (memq 'todo conditions)))
- (org-agenda-skip-if-todo m end)))
- end)))
-
-(defun org-agenda-skip-if-todo (args end)
- "Helper function for `org-agenda-skip-if', do not use it directly.
-ARGS is a list with first element either `todo', `nottodo',
-`todo-unblocked' or `nottodo-unblocked'. The remainder is either
-a list of TODO keywords, or a state symbol `todo' or `done' or
-`any'."
- (let ((todo-re
- (concat "^\\*+[ \t]+"
- (regexp-opt
- (pcase args
- (`(,_ todo)
- (org-delete-all org-done-keywords
- (copy-sequence org-todo-keywords-1)))
- (`(,_ done) org-done-keywords)
- (`(,_ any) org-todo-keywords-1)
- (`(,_ ,(pred atom))
- (error "Invalid TODO class or type: %S" args))
- (`(,_ ,(pred (member "*"))) org-todo-keywords-1)
- (`(,_ ,todo-list) todo-list))
- 'words))))
- (pcase args
- (`(todo . ,_)
- (let (case-fold-search) (re-search-forward todo-re end t)))
- (`(nottodo . ,_)
- (not (let (case-fold-search) (re-search-forward todo-re end t))))
- (`(todo-unblocked . ,_)
- (catch :unblocked
- (while (let (case-fold-search) (re-search-forward todo-re end t))
- (when (org-entry-blocked-p) (throw :unblocked t)))
- nil))
- (`(nottodo-unblocked . ,_)
- (catch :unblocked
- (while (let (case-fold-search) (re-search-forward todo-re end t))
- (when (org-entry-blocked-p) (throw :unblocked nil)))
- t))
- (`(,type . ,_) (error "Unknown TODO skip type: %S" type)))))
-
-;;;###autoload
-(defun org-agenda-list-stuck-projects (&rest _ignore)
- "Create agenda view for projects that are stuck.
-Stuck projects are project that have no next actions. For the definitions
-of what a project is and how to check if it stuck, customize the variable
-`org-stuck-projects'."
- (interactive)
- (let* ((org-agenda-overriding-header
- (or org-agenda-overriding-header "List of stuck projects: "))
- (matcher (nth 0 org-stuck-projects))
- (todo (nth 1 org-stuck-projects))
- (tags (nth 2 org-stuck-projects))
- (gen-re (org-string-nw-p (nth 3 org-stuck-projects)))
- (todo-wds
- (if (not (member "*" todo)) todo
- (org-agenda-prepare-buffers (org-agenda-files nil 'ifmode))
- (org-delete-all org-done-keywords-for-agenda
- (copy-sequence org-todo-keywords-for-agenda))))
- (todo-re (and todo
- (format "^\\*+[ \t]+\\(%s\\)\\>"
- (mapconcat #'identity todo-wds "\\|"))))
- (tags-re (cond ((null tags) nil)
- ((member "*" tags) org-tag-line-re)
- (tags
- (let ((other-tags (format "\\(?:%s:\\)*" org-tag-re)))
- (concat org-outline-regexp-bol
- ".*?[ \t]:"
- other-tags
- (regexp-opt tags t)
- ":" other-tags "[ \t]*$")))
- (t nil)))
- (re-list (delq nil (list todo-re tags-re gen-re)))
- (skip-re
- (if (null re-list)
- (error "Missing information to identify unstuck projects")
- (mapconcat #'identity re-list "\\|")))
- (org-agenda-skip-function
- ;; Skip entry if `org-agenda-skip-regexp' matches anywhere
- ;; in the subtree.
- (lambda ()
- (and (save-excursion
- (let ((case-fold-search nil))
- (re-search-forward
- skip-re (save-excursion (org-end-of-subtree t)) t)))
- (progn (outline-next-heading) (point))))))
- (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))
- (let ((inhibit-read-only t))
- (add-text-properties
- (point-min) (point-max)
- `(org-redo-cmd ,org-agenda-redo-command))))))
-
-;;; Diary integration
-
-(defvar org-disable-agenda-to-diary nil) ;Dynamically-scoped param.
-(defvar diary-list-entries-hook)
-(defvar diary-time-regexp)
-(defvar diary-modify-entry-list-string-function)
-(defvar diary-file-name-prefix)
-(defvar diary-display-function)
-
-(defun org-get-entries-from-diary (date)
- "Get the (Emacs Calendar) diary entries for DATE."
- (require 'diary-lib)
- (declare-function diary-fancy-display "diary-lib" ())
- (let* ((diary-fancy-buffer "*temporary-fancy-diary-buffer*")
- (diary-display-function #'diary-fancy-display)
- (pop-up-frames nil)
- (diary-list-entries-hook
- (cons 'org-diary-default-entry diary-list-entries-hook))
- (diary-file-name-prefix nil) ; turn this feature off
- (diary-modify-entry-list-string-function
- #'org-modify-diary-entry-string)
- (diary-time-regexp (concat "^" diary-time-regexp))
- entries
- (org-disable-agenda-to-diary t))
- (save-excursion
- (save-window-excursion
- (diary-list-entries date 1)))
- (if (not (get-buffer diary-fancy-buffer))
- (setq entries nil)
- (with-current-buffer diary-fancy-buffer
- (setq buffer-read-only nil)
- (if (zerop (buffer-size))
- ;; No entries
- (setq entries nil)
- ;; Omit the date and other unnecessary stuff
- (org-agenda-cleanup-fancy-diary)
- ;; Add prefix to each line and extend the text properties
- (if (zerop (buffer-size))
- (setq entries nil)
- (setq entries (buffer-substring (point-min) (- (point-max) 1)))
- (setq entries
- (with-temp-buffer
- (insert entries) (goto-char (point-min))
- (while (re-search-forward "\n[ \t]+\\(.+\\)$" nil t)
- (unless (save-match-data (string-match diary-time-regexp (match-string 1)))
- (replace-match (concat "; " (match-string 1)))))
- (buffer-string)))))
- (set-buffer-modified-p nil)
- (kill-buffer diary-fancy-buffer)))
- (when entries
- (setq entries (org-split-string entries "\n"))
- (setq entries
- (mapcar
- (lambda (x)
- (setq x (org-agenda-format-item "" x nil "Diary" nil 'time))
- ;; Extend the text properties to the beginning of the line
- (org-add-props x (text-properties-at (1- (length x)) x)
- 'type "diary" 'date date 'face 'org-agenda-diary))
- entries)))))
-
-(defvar org-agenda-cleanup-fancy-diary-hook nil
- "Hook run when the fancy diary buffer is cleaned up.")
-
-(defun org-agenda-cleanup-fancy-diary ()
- "Remove unwanted stuff in buffer created by `fancy-diary-display'.
-This gets rid of the date, the underline under the date, and the
-dummy entry installed by Org mode to ensure non-empty diary for
-each date. It also removes lines that contain only whitespace."
- (goto-char (point-min))
- (if (looking-at ".*?:[ \t]*")
- (progn
- (replace-match "")
- (re-search-forward "\n=+$" nil t)
- (replace-match "")
- (while (re-search-backward "^ +\n?" nil t) (replace-match "")))
- (re-search-forward "\n=+$" nil t)
- (delete-region (point-min) (min (point-max) (1+ (match-end 0)))))
- (goto-char (point-min))
- (while (re-search-forward "^ +\n" nil t)
- (replace-match ""))
- (goto-char (point-min))
- (when (re-search-forward "^Org mode dummy\n?" nil t)
- (replace-match ""))
- (run-hooks 'org-agenda-cleanup-fancy-diary-hook))
-
-(defun org-modify-diary-entry-string (string)
- "Add text properties to string, allowing Org to act on it."
- (org-add-props string nil
- 'mouse-face 'highlight
- 'help-echo (if buffer-file-name
- (format "mouse-2 or RET jump to diary file %s"
- (abbreviate-file-name buffer-file-name))
- "")
- 'org-agenda-diary-link t
- 'org-marker (org-agenda-new-marker (point-at-bol))))
-
-(defun org-diary-default-entry ()
- "Add a dummy entry to the diary.
-Needed to avoid empty dates which mess up holiday display."
- ;; Catch the error if dealing with the new add-to-diary-alist
- (when org-disable-agenda-to-diary
- (diary-add-to-list original-date "Org mode dummy" "")))
-
-(defvar org-diary-last-run-time nil)
-
-;;;###autoload
-(defun org-diary (&rest args)
- "Return diary information from org files.
-This function can be used in a \"sexp\" diary entry in the Emacs calendar.
-It accesses org files and extracts information from those files to be
-listed in the diary. The function accepts arguments specifying what
-items should be listed. For a list of arguments allowed here, see the
-variable `org-agenda-entry-types'.
-
-The call in the diary file should look like this:
-
- &%%(org-diary) ~/path/to/some/orgfile.org
-
-Use a separate line for each org file to check. Or, if you omit the file name,
-all files listed in `org-agenda-files' will be checked automatically:
-
- &%%(org-diary)
-
-If you don't give any arguments (as in the example above), the default value
-of `org-agenda-entry-types' is used: (:deadline :scheduled :timestamp :sexp).
-So the example above may also be written as
-
- &%%(org-diary :deadline :timestamp :sexp :scheduled)
-
-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."
- (with-no-warnings (defvar date) (defvar entry))
- (when (> (- (float-time)
- org-agenda-last-marker-time)
- 5)
- ;; I am not sure if this works with sticky agendas, because the marker
- ;; list is then no longer a global variable.
- (org-agenda-reset-markers))
- (org-compile-prefix-format 'agenda)
- (org-set-sorting-strategy 'agenda)
- (setq args (or args org-agenda-entry-types))
- (let* ((files (if (and entry (stringp entry) (string-match "\\S-" entry))
- (list entry)
- (org-agenda-files t)))
- (time (float-time))
- file rtn results)
- (when (or (not org-diary-last-run-time)
- (> (- time
- org-diary-last-run-time)
- 3))
- (org-agenda-prepare-buffers files))
- (setq org-diary-last-run-time time)
- ;; If this is called during org-agenda, don't return any entries to
- ;; the calendar. Org Agenda will list these entries itself.
- (when org-disable-agenda-to-diary (setq files nil))
- (while (setq file (pop files))
- (setq rtn (apply #'org-agenda-get-day-entries file date args))
- (setq results (append results rtn)))
- (when results
- (setq results
- (mapcar (lambda (i) (replace-regexp-in-string
- org-link-bracket-re "\\2" i))
- results))
- (concat (org-agenda-finalize-entries results) "\n"))))
-
-;;; Agenda entry finders
-
-(defun org-agenda--timestamp-to-absolute (&rest args)
- "Call `org-time-string-to-absolute' with ARGS.
-However, throw `:skip' whenever an error is raised."
- (condition-case e
- (apply #'org-time-string-to-absolute args)
- (org-diary-sexp-no-match (throw :skip nil))
- (error
- (message "%s; Skipping entry" (error-message-string e))
- (throw :skip nil))))
-
-(defun org-agenda-get-day-entries (file date &rest args)
- "Does the work for `org-diary' and `org-agenda'.
-FILE is the path to a file to be checked for entries. DATE is date like
-the one returned by `calendar-current-date'. ARGS are symbols indicating
-which kind of entries should be extracted. For details about these, see
-the documentation of `org-diary'."
- (let* ((org-startup-folded nil)
- (org-startup-align-all-tables nil)
- (buffer (if (file-exists-p file) (org-get-agenda-file-buffer file)
- (error "No such file %s" file))))
- (if (not buffer)
- ;; If file does not exist, signal it in diary nonetheless.
- (list (format "ORG-AGENDA-ERROR: No such org-file %s" file))
- (with-current-buffer buffer
- (unless (derived-mode-p 'org-mode)
- (error "Agenda file %s is not in Org mode" file))
- (setq org-agenda-buffer (or org-agenda-buffer buffer))
- (setf org-agenda-current-date date)
- (save-excursion
- (save-restriction
- (if (eq buffer org-agenda-restrict)
- (narrow-to-region org-agenda-restrict-begin
- org-agenda-restrict-end)
- (widen))
- ;; Rationalize ARGS. Also make sure `:deadline' comes
- ;; first in order to populate DEADLINES before passing it.
- ;;
- ;; We use `delq' since `org-uniquify' duplicates ARGS,
- ;; guarding us from modifying `org-agenda-entry-types'.
- (setf args (org-uniquify (or args org-agenda-entry-types)))
- (when (and (memq :scheduled args) (memq :scheduled* args))
- (setf args (delq :scheduled* args)))
- (cond
- ((memq :deadline args)
- (setf args (cons :deadline
- (delq :deadline (delq :deadline* args)))))
- ((memq :deadline* args)
- (setf args (cons :deadline* (delq :deadline* args)))))
- ;; Collect list of headlines. Return them flattened.
- (let ((case-fold-search nil) results deadlines)
- (org-dlet
- ((date date))
- (dolist (arg args (apply #'nconc (nreverse results)))
- (pcase arg
- ((and :todo (guard (org-agenda-today-p date)))
- (push (org-agenda-get-todos) results))
- (:timestamp
- (push (org-agenda-get-blocks) results)
- (push (org-agenda-get-timestamps deadlines) results))
- (:sexp
- (push (org-agenda-get-sexps) results))
- (:scheduled
- (push (org-agenda-get-scheduled deadlines) results))
- (:scheduled*
- (push (org-agenda-get-scheduled deadlines t) results))
- (:closed
- (push (org-agenda-get-progress) results))
- (:deadline
- (setf deadlines (org-agenda-get-deadlines))
- (push deadlines results))
- (:deadline*
- (setf deadlines (org-agenda-get-deadlines t))
- (push deadlines results))))))))))))
-
-(defsubst org-em (x y list)
- "Is X or Y a member of LIST?"
- (or (memq x list) (memq y list)))
-
-(defvar org-heading-keyword-regexp-format) ; defined in org.el
-(defvar org-agenda-sorting-strategy-selected nil)
-
-(defun org-agenda-entry-get-agenda-timestamp (pom)
- "Retrieve timestamp information for sorting agenda views.
-Given a point or marker POM, returns a cons cell of the timestamp
-and the timestamp type relevant for the sorting strategy in
-`org-agenda-sorting-strategy-selected'."
- (let (ts ts-date-type)
- (save-match-data
- (cond ((org-em 'scheduled-up 'scheduled-down
- org-agenda-sorting-strategy-selected)
- (setq ts (org-entry-get pom "SCHEDULED")
- ts-date-type " scheduled"))
- ((org-em 'deadline-up 'deadline-down
- org-agenda-sorting-strategy-selected)
- (setq ts (org-entry-get pom "DEADLINE")
- ts-date-type " deadline"))
- ((org-em 'ts-up 'ts-down
- org-agenda-sorting-strategy-selected)
- (setq ts (org-entry-get pom "TIMESTAMP")
- ts-date-type " timestamp"))
- ((org-em 'tsia-up 'tsia-down
- org-agenda-sorting-strategy-selected)
- (setq ts (org-entry-get pom "TIMESTAMP_IA")
- ts-date-type " timestamp_ia"))
- ((org-em 'timestamp-up 'timestamp-down
- org-agenda-sorting-strategy-selected)
- (setq ts (or (org-entry-get pom "SCHEDULED")
- (org-entry-get pom "DEADLINE")
- (org-entry-get pom "TIMESTAMP")
- (org-entry-get pom "TIMESTAMP_IA"))
- ts-date-type ""))
- (t (setq ts-date-type "")))
- (cons (when ts (ignore-errors (org-time-string-to-absolute ts)))
- ts-date-type))))
-
-(defun org-agenda-get-todos ()
- "Return the TODO information for agenda display."
- (let* ((props (list 'face nil
- 'done-face 'org-agenda-done
- 'org-not-done-regexp org-not-done-regexp
- 'org-todo-regexp org-todo-regexp
- 'org-complex-heading-regexp org-complex-heading-regexp
- 'mouse-face 'highlight
- 'help-echo
- (format "mouse-2 or RET jump to org file %s"
- (abbreviate-file-name buffer-file-name))))
- (case-fold-search nil)
- (regexp (format org-heading-keyword-regexp-format
- (cond
- ((and org-select-this-todo-keyword
- (equal org-select-this-todo-keyword "*"))
- org-todo-regexp)
- (org-select-this-todo-keyword
- (concat "\\("
- (mapconcat #'identity
- (org-split-string
- org-select-this-todo-keyword
- "|")
- "\\|")
- "\\)"))
- (t org-not-done-regexp))))
- marker priority category level tags todo-state
- ts-date ts-date-type ts-date-pair
- ee txt beg end inherited-tags todo-state-end-pos)
- (goto-char (point-min))
- (while (re-search-forward regexp nil t)
- (catch :skip
- (save-match-data
- (beginning-of-line)
- (org-agenda-skip)
- (setq beg (point) end (save-excursion (outline-next-heading) (point)))
- (unless (and (setq todo-state (org-get-todo-state))
- (setq todo-state-end-pos (match-end 2)))
- (goto-char end)
- (throw :skip nil))
- (when (org-agenda-check-for-timestamp-as-reason-to-ignore-todo-item end)
- (goto-char (1+ beg))
- (or org-agenda-todo-list-sublevels (org-end-of-subtree 'invisible))
- (throw :skip nil)))
- (goto-char (match-beginning 2))
- (setq marker (org-agenda-new-marker (match-beginning 0))
- category (org-get-category)
- ts-date-pair (org-agenda-entry-get-agenda-timestamp (point))
- ts-date (car ts-date-pair)
- ts-date-type (cdr ts-date-pair)
- txt (org-trim (buffer-substring (match-beginning 2) (match-end 0)))
- inherited-tags
- (or (eq org-agenda-show-inherited-tags 'always)
- (and (listp org-agenda-show-inherited-tags)
- (memq 'todo org-agenda-show-inherited-tags))
- (and (eq org-agenda-show-inherited-tags t)
- (or (eq org-agenda-use-tag-inheritance t)
- (memq 'todo org-agenda-use-tag-inheritance))))
- tags (org-get-tags nil (not inherited-tags))
- level (make-string (org-reduced-level (org-outline-level)) ? )
- txt (org-agenda-format-item "" txt level category tags t)
- priority (1+ (org-get-priority txt)))
- (org-add-props txt props
- 'org-marker marker 'org-hd-marker marker
- 'priority priority
- 'level level
- 'ts-date ts-date
- 'type (concat "todo" ts-date-type) 'todo-state todo-state)
- (push txt ee)
- (if org-agenda-todo-list-sublevels
- (goto-char todo-state-end-pos)
- (org-end-of-subtree 'invisible))))
- (nreverse ee)))
-
-(defun org-agenda-todo-custom-ignore-p (time n)
- "Check whether timestamp is farther away than n number of days.
-This function is invoked if `org-agenda-todo-ignore-deadlines',
-`org-agenda-todo-ignore-scheduled' or
-`org-agenda-todo-ignore-timestamp' is set to an integer."
- (let ((days (org-time-stamp-to-now
- time org-agenda-todo-ignore-time-comparison-use-seconds)))
- (if (>= n 0)
- (>= days n)
- (<= days n))))
-
-;;;###autoload
-(defun org-agenda-check-for-timestamp-as-reason-to-ignore-todo-item
- (&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
- org-agenda-todo-ignore-deadlines
- org-agenda-todo-ignore-timestamp)
- (setq end (or end (save-excursion (outline-next-heading) (point))))
- (save-excursion
- (or (and org-agenda-todo-ignore-with-date
- (re-search-forward org-ts-regexp end t))
- (and org-agenda-todo-ignore-scheduled
- (re-search-forward org-scheduled-time-regexp end t)
- (cond
- ((eq org-agenda-todo-ignore-scheduled 'future)
- (> (org-time-stamp-to-now
- (match-string 1) org-agenda-todo-ignore-time-comparison-use-seconds)
- 0))
- ((eq org-agenda-todo-ignore-scheduled 'past)
- (<= (org-time-stamp-to-now
- (match-string 1) org-agenda-todo-ignore-time-comparison-use-seconds)
- 0))
- ((numberp org-agenda-todo-ignore-scheduled)
- (org-agenda-todo-custom-ignore-p
- (match-string 1) org-agenda-todo-ignore-scheduled))
- (t)))
- (and org-agenda-todo-ignore-deadlines
- (re-search-forward org-deadline-time-regexp end t)
- (cond
- ((eq org-agenda-todo-ignore-deadlines 'all) t)
- ((eq org-agenda-todo-ignore-deadlines 'far)
- (not (org-deadline-close-p (match-string 1))))
- ((eq org-agenda-todo-ignore-deadlines 'future)
- (> (org-time-stamp-to-now
- (match-string 1) org-agenda-todo-ignore-time-comparison-use-seconds)
- 0))
- ((eq org-agenda-todo-ignore-deadlines 'past)
- (<= (org-time-stamp-to-now
- (match-string 1) org-agenda-todo-ignore-time-comparison-use-seconds)
- 0))
- ((numberp org-agenda-todo-ignore-deadlines)
- (org-agenda-todo-custom-ignore-p
- (match-string 1) org-agenda-todo-ignore-deadlines))
- (t (org-deadline-close-p (match-string 1)))))
- (and org-agenda-todo-ignore-timestamp
- (let ((buffer (current-buffer))
- (regexp
- (concat
- org-scheduled-time-regexp "\\|" org-deadline-time-regexp))
- (start (point)))
- ;; Copy current buffer into a temporary one
- (with-temp-buffer
- (insert-buffer-substring buffer start end)
- (goto-char (point-min))
- ;; Delete SCHEDULED and DEADLINE items
- (while (re-search-forward regexp end t)
- (delete-region (match-beginning 0) (match-end 0)))
- (goto-char (point-min))
- ;; No search for timestamp left
- (when (re-search-forward org-ts-regexp nil t)
- (cond
- ((eq org-agenda-todo-ignore-timestamp 'future)
- (> (org-time-stamp-to-now
- (match-string 1) org-agenda-todo-ignore-time-comparison-use-seconds)
- 0))
- ((eq org-agenda-todo-ignore-timestamp 'past)
- (<= (org-time-stamp-to-now
- (match-string 1) org-agenda-todo-ignore-time-comparison-use-seconds)
- 0))
- ((numberp org-agenda-todo-ignore-timestamp)
- (org-agenda-todo-custom-ignore-p
- (match-string 1) org-agenda-todo-ignore-timestamp))
- (t))))))))))
-
-(defun org-agenda-get-timestamps (&optional deadlines)
- "Return the date stamp information for agenda display.
-Optional argument DEADLINES is a list of deadline items to be
-displayed in agenda view."
- (with-no-warnings (defvar date))
- (let* ((props (list 'face 'org-agenda-calendar-event
- 'org-not-done-regexp org-not-done-regexp
- 'org-todo-regexp org-todo-regexp
- 'org-complex-heading-regexp org-complex-heading-regexp
- 'mouse-face 'highlight
- 'help-echo
- (format "mouse-2 or RET jump to Org file %s"
- (abbreviate-file-name buffer-file-name))))
- (current (calendar-absolute-from-gregorian date))
- (today (org-today))
- (deadline-position-alist
- (mapcar (lambda (d)
- (let ((m (get-text-property 0 'org-hd-marker d)))
- (and m (marker-position m))))
- deadlines))
- ;; Match time-stamps set to current date, time-stamps with
- ;; a repeater, and S-exp time-stamps.
- (regexp
- (concat
- (if org-agenda-include-inactive-timestamps "[[<]" "<")
- (regexp-quote
- (substring
- (format-time-string
- (car org-time-stamp-formats)
- (encode-time ; DATE bound by calendar
- 0 0 0 (nth 1 date) (car date) (nth 2 date)))
- 1 11))
- "\\|\\(<[0-9]+-[0-9]+-[0-9]+[^>\n]+?\\+[0-9]+[hdwmy]>\\)"
- "\\|\\(<%%\\(([^>\n]+)\\)>\\)"))
- timestamp-items)
- (goto-char (point-min))
- (while (re-search-forward regexp nil t)
- ;; Skip date ranges, scheduled and deadlines, which are handled
- ;; specially. Also skip time-stamps before first headline as
- ;; there would be no entry to add to the agenda. Eventually,
- ;; ignore clock entries.
- (catch :skip
- (save-match-data
- (when (or (org-at-date-range-p)
- (org-at-planning-p)
- (org-before-first-heading-p)
- (and org-agenda-include-inactive-timestamps
- (org-at-clock-log-p)))
- (throw :skip nil))
- (org-agenda-skip))
- (let* ((pos (match-beginning 0))
- (repeat (match-string 1))
- (sexp-entry (match-string 3))
- (time-stamp (if (or repeat sexp-entry) (match-string 0)
- (save-excursion
- (goto-char pos)
- (looking-at org-ts-regexp-both)
- (match-string 0))))
- (todo-state (org-get-todo-state))
- (warntime (get-text-property (point) 'org-appt-warntime))
- (done? (member todo-state org-done-keywords)))
- ;; Possibly skip done tasks.
- (when (and done? org-agenda-skip-timestamp-if-done)
- (throw :skip t))
- ;; S-exp entry doesn't match current day: skip it.
- (when (and sexp-entry (not (org-diary-sexp-entry sexp-entry "" date)))
- (throw :skip nil))
- (when repeat
- (let* ((past
- ;; A repeating time stamp is shown at its base
- ;; date and every repeated date up to TODAY. If
- ;; `org-agenda-prefer-last-repeat' is non-nil,
- ;; however, only the last repeat before today
- ;; (inclusive) is shown.
- (org-agenda--timestamp-to-absolute
- repeat
- (if (or (> current today)
- (eq org-agenda-prefer-last-repeat t)
- (member todo-state org-agenda-prefer-last-repeat))
- today
- current)
- 'past (current-buffer) pos))
- (future
- ;; Display every repeated date past TODAY
- ;; (exclusive) unless
- ;; `org-agenda-show-future-repeats' is nil. If
- ;; this variable is set to `next', only display
- ;; the first repeated date after TODAY
- ;; (exclusive).
- (cond
- ((<= current today) past)
- ((not org-agenda-show-future-repeats) past)
- (t
- (let ((base (if (eq org-agenda-show-future-repeats 'next)
- (1+ today)
- current)))
- (org-agenda--timestamp-to-absolute
- repeat base 'future (current-buffer) pos))))))
- (when (and (/= current past) (/= current future))
- (throw :skip nil))))
- (save-excursion
- (re-search-backward org-outline-regexp-bol nil t)
- ;; Possibly skip time-stamp when a deadline is set.
- (when (and org-agenda-skip-timestamp-if-deadline-is-shown
- (assq (point) deadline-position-alist))
- (throw :skip nil))
- (let* ((category (org-get-category pos))
- (inherited-tags
- (or (eq org-agenda-show-inherited-tags 'always)
- (and (consp org-agenda-show-inherited-tags)
- (memq 'agenda org-agenda-show-inherited-tags))
- (and (eq org-agenda-show-inherited-tags t)
- (or (eq org-agenda-use-tag-inheritance t)
- (memq 'agenda
- org-agenda-use-tag-inheritance)))))
- (tags (org-get-tags nil (not inherited-tags)))
- (level (make-string (org-reduced-level (org-outline-level))
- ?\s))
- (head (and (looking-at "\\*+[ \t]+\\(.*\\)")
- (match-string 1)))
- (inactive? (= (char-after pos) ?\[))
- (habit? (and (fboundp 'org-is-habit-p) (org-is-habit-p)))
- (item
- (org-agenda-format-item
- (and inactive? org-agenda-inactive-leader)
- head level category tags time-stamp org-ts-regexp habit?)))
- (org-add-props item props
- 'priority (if habit?
- (org-habit-get-priority (org-habit-parse-todo))
- (org-get-priority item))
- 'org-marker (org-agenda-new-marker pos)
- 'org-hd-marker (org-agenda-new-marker)
- 'date date
- 'level level
- 'ts-date (if repeat (org-agenda--timestamp-to-absolute repeat)
- current)
- 'todo-state todo-state
- 'warntime warntime
- 'type "timestamp")
- (push item timestamp-items))))
- (when org-agenda-skip-additional-timestamps-same-entry
- (outline-next-heading))))
- (nreverse timestamp-items)))
-
-(defun org-agenda-get-sexps ()
- "Return the sexp information for agenda display."
- (require 'diary-lib)
- (with-no-warnings (defvar date) (defvar entry))
- (let* ((props (list 'face 'org-agenda-calendar-sexp
- 'mouse-face 'highlight
- 'help-echo
- (format "mouse-2 or RET jump to org file %s"
- (abbreviate-file-name buffer-file-name))))
- (regexp "^&?%%(")
- ;; FIXME: Is this `entry' binding intended to be dynamic,
- ;; so as to "hide" any current binding for it?
- marker category extra level ee txt tags entry
- result beg b sexp sexp-entry todo-state warntime inherited-tags)
- (goto-char (point-min))
- (while (re-search-forward regexp nil t)
- (catch :skip
- (org-agenda-skip)
- (setq beg (match-beginning 0))
- (goto-char (1- (match-end 0)))
- (setq b (point))
- (forward-sexp 1)
- (setq sexp (buffer-substring b (point)))
- (setq sexp-entry (if (looking-at "[ \t]*\\(\\S-.*\\)")
- (org-trim (match-string 1))
- ""))
- (setq result (org-diary-sexp-entry sexp sexp-entry date))
- (when result
- (setq marker (org-agenda-new-marker beg)
- level (make-string (org-reduced-level (org-outline-level)) ? )
- category (org-get-category beg)
- inherited-tags
- (or (eq org-agenda-show-inherited-tags 'always)
- (and (listp org-agenda-show-inherited-tags)
- (memq 'agenda org-agenda-show-inherited-tags))
- (and (eq org-agenda-show-inherited-tags t)
- (or (eq org-agenda-use-tag-inheritance t)
- (memq 'agenda org-agenda-use-tag-inheritance))))
- tags (org-get-tags nil (not inherited-tags))
- todo-state (org-get-todo-state)
- warntime (get-text-property (point) 'org-appt-warntime)
- extra nil)
-
- (dolist (r (if (stringp result)
- (list result)
- result)) ;; we expect a list here
- (when (and org-agenda-diary-sexp-prefix
- (string-match org-agenda-diary-sexp-prefix r))
- (setq extra (match-string 0 r)
- r (replace-match "" nil nil r)))
- (if (string-match "\\S-" r)
- (setq txt r)
- (setq txt "SEXP entry returned empty string"))
- (setq txt (org-agenda-format-item extra txt level category tags 'time))
- (org-add-props txt props 'org-marker marker
- 'date date 'todo-state todo-state
- 'level level 'type "sexp" 'warntime warntime)
- (push txt ee)))))
- (nreverse ee)))
-
-;; Calendar sanity: define some functions that are independent of
-;; `calendar-date-style'.
-(defun org-anniversary (year month day &optional mark)
- "Like `diary-anniversary', but with fixed (ISO) order of arguments."
- (with-no-warnings
- (let ((calendar-date-style 'iso))
- (diary-anniversary year month day mark))))
-(defun org-cyclic (N year month day &optional mark)
- "Like `diary-cyclic', but with fixed (ISO) order of arguments."
- (with-no-warnings
- (let ((calendar-date-style 'iso))
- (diary-cyclic N year month day mark))))
-(defun org-block (Y1 M1 D1 Y2 M2 D2 &optional mark)
- "Like `diary-block', but with fixed (ISO) order of arguments."
- (with-no-warnings
- (let ((calendar-date-style 'iso))
- (diary-block Y1 M1 D1 Y2 M2 D2 mark))))
-(defun org-date (year month day &optional mark)
- "Like `diary-date', but with fixed (ISO) order of arguments."
- (with-no-warnings
- (let ((calendar-date-style 'iso))
- (diary-date year month day mark))))
-
-;; 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).
-SKIP-WEEKS is any number of ISO weeks in the block period for which the
-item should be skipped. If any of the SKIP-WEEKS arguments is the symbol
-`holidays', then any date that is known by the Emacs calendar to be a
-holiday will also be skipped. If SKIP-WEEKS arguments are holiday strings,
-then those holidays will be skipped."
- (with-no-warnings (defvar date) (defvar entry))
- (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))
- (h (when skip-weeks (calendar-check-holidays date))))
- (and
- (<= date1 d)
- (<= d date2)
- (= (calendar-day-of-week date) dayname)
- (or (not skip-weeks)
- (progn
- (require 'cal-iso)
- (not (member (car (calendar-iso-from-absolute d)) skip-weeks))))
- (not (or (and h (memq 'holidays skip-weeks))
- (delq nil (mapcar (lambda(g) (member g skip-weeks)) h))))
- entry)))
-
-(defalias 'org-get-closed #'org-agenda-get-progress)
-(defun org-agenda-get-progress ()
- "Return the logged TODO entries for agenda display."
- (with-no-warnings (defvar date))
- (let* ((props (list 'mouse-face 'highlight
- 'org-not-done-regexp org-not-done-regexp
- 'org-todo-regexp org-todo-regexp
- 'org-complex-heading-regexp org-complex-heading-regexp
- 'help-echo
- (format "mouse-2 or RET jump to org file %s"
- (abbreviate-file-name buffer-file-name))))
- (items (if (consp org-agenda-show-log-scoped)
- org-agenda-show-log-scoped
- (if (eq org-agenda-show-log-scoped 'clockcheck)
- '(clock)
- org-agenda-log-mode-items)))
- (parts
- (delq nil
- (list
- (when (memq 'closed items) (concat "\\<" org-closed-string))
- (when (memq 'clock items) (concat "\\<" org-clock-string))
- (when (memq 'state items)
- (format "- +State \"%s\".*?" org-todo-regexp)))))
- (parts-re (if parts (mapconcat #'identity parts "\\|")
- (error "`org-agenda-log-mode-items' is empty")))
- (regexp (concat
- "\\(" parts-re "\\)"
- " *\\["
- (regexp-quote
- (substring
- (format-time-string
- (car org-time-stamp-formats)
- (encode-time ; DATE bound by calendar
- 0 0 0 (nth 1 date) (car date) (nth 2 date)))
- 1 11))))
- (org-agenda-search-headline-for-time nil)
- marker hdmarker priority category level tags closedp type
- statep clockp state ee txt extra timestr rest clocked inherited-tags)
- (goto-char (point-min))
- (while (re-search-forward regexp nil t)
- (catch :skip
- (org-agenda-skip)
- (setq marker (org-agenda-new-marker (match-beginning 0))
- closedp (equal (match-string 1) org-closed-string)
- statep (equal (string-to-char (match-string 1)) ?-)
- 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)))
- (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))
- (progn (setq timestr (concat (substring timestr 0 -1)
- "-" (match-string 1 rest) "]"))
- (setq clocked (match-string 2 rest)))
- (setq clocked "-")))
- (save-excursion
- (setq extra
- (cond
- ((not org-agenda-log-mode-add-notes) nil)
- (statep
- (and (looking-at ".*\\\\\n[ \t]*\\([^-\n \t].*?\\)[ \t]*$")
- (match-string 1)))
- (clockp
- (and (looking-at ".*\n[ \t]*-[ \t]+\\([^-\n \t].*?\\)[ \t]*$")
- (match-string 1)))))
- (if (not (re-search-backward org-outline-regexp-bol nil t))
- (throw :skip nil)
- (goto-char (match-beginning 0))
- (setq hdmarker (org-agenda-new-marker)
- inherited-tags
- (or (eq org-agenda-show-inherited-tags 'always)
- (and (listp org-agenda-show-inherited-tags)
- (memq 'todo org-agenda-show-inherited-tags))
- (and (eq org-agenda-show-inherited-tags t)
- (or (eq org-agenda-use-tag-inheritance t)
- (memq 'todo org-agenda-use-tag-inheritance))))
- tags (org-get-tags nil (not inherited-tags))
- level (make-string (org-reduced-level (org-outline-level)) ? ))
- (looking-at "\\*+[ \t]+\\([^\r\n]+\\)")
- (setq txt (match-string 1))
- (when extra
- (if (string-match "\\([ \t]+\\)\\(:[^ \n\t]*?:\\)[ \t]*$" txt)
- (setq txt (concat (substring txt 0 (match-beginning 1))
- " - " extra " " (match-string 2 txt)))
- (setq txt (concat txt " - " extra))))
- (setq txt (org-agenda-format-item
- (cond
- (closedp "Closed: ")
- (statep (concat "State: (" state ")"))
- (t (concat "Clocked: (" clocked ")")))
- txt level category tags timestr)))
- (setq type (cond (closedp "closed")
- (statep "state")
- (t "clock")))
- (setq priority 100000)
- (org-add-props txt props
- 'org-marker marker 'org-hd-marker hdmarker 'face 'org-agenda-done
- 'priority priority 'level level
- 'type type 'date date
- 'undone-face 'org-warning 'done-face 'org-agenda-done)
- (push txt ee))
- (goto-char (point-at-eol))))
- (nreverse ee)))
-
-(defun org-agenda-show-clocking-issues ()
- "Add overlays, showing issues with clocking.
-See also the user option `org-agenda-clock-consistency-checks'."
- (interactive)
- (let* ((pl org-agenda-clock-consistency-checks)
- (re (concat "^[ \t]*"
- org-clock-string
- "[ \t]+"
- "\\(\\[.*?\\]\\)" ; group 1 is first stamp
- "\\(-\\{1,3\\}\\(\\[.*?\\]\\)\\)?")) ; group 3 is second
- (tlstart 0.)
- (tlend 0.)
- (maxtime (org-duration-to-minutes
- (or (plist-get pl :max-duration) "24:00")))
- (mintime (org-duration-to-minutes
- (or (plist-get pl :min-duration) 0)))
- (maxgap (org-duration-to-minutes
- ;; default 30:00 means never complain
- (or (plist-get pl :max-gap) "30:00")))
- (gapok (mapcar #'org-duration-to-minutes
- (plist-get pl :gap-ok-around)))
- (def-face (or (plist-get pl :default-face)
- '((:background "DarkRed") (:foreground "white"))))
- issue face m te ts dt ov)
- (goto-char (point-min))
- (while (re-search-forward " Clocked: +(\\(?:-\\|\\([0-9]+:[0-9]+\\)\\))" nil t)
- (setq issue nil face def-face)
- (catch 'next
- (setq m (org-get-at-bol 'org-marker)
- te nil ts nil)
- (unless (and m (markerp m))
- (setq issue "No valid clock line") (throw 'next t))
- (org-with-point-at m
- (save-excursion
- (goto-char (point-at-bol))
- (unless (looking-at re)
- (error "No valid Clock line")
- (throw 'next t))
- (unless (match-end 3)
- (setq issue
- (format
- "No end time: (%s)"
- (org-duration-from-minutes
- (floor
- (- (float-time (org-current-time))
- (float-time (org-time-string-to-time (match-string 1))))
- 60)))
- face (or (plist-get pl :no-end-time-face) face))
- (throw 'next t))
- (setq ts (match-string 1)
- te (match-string 3)
- ts (float-time (org-time-string-to-time ts))
- te (float-time (org-time-string-to-time te))
- dt (- te ts))))
- (cond
- ((> dt (* 60 maxtime))
- ;; a very long clocking chunk
- (setq issue (format "Clocking interval is very long: %s"
- (org-duration-from-minutes (floor dt 60)))
- face (or (plist-get pl :long-face) face)))
- ((< dt (* 60 mintime))
- ;; a very short clocking chunk
- (setq issue (format "Clocking interval is very short: %s"
- (org-duration-from-minutes (floor dt 60)))
- face (or (plist-get pl :short-face) face)))
- ((and (> tlend 0) (< ts tlend))
- ;; Two clock entries are overlapping
- (setq issue (format "Clocking overlap: %d minutes"
- (/ (- tlend ts) 60))
- face (or (plist-get pl :overlap-face) face)))
- ((and (> tlend 0) (> ts (+ tlend (* 60 maxgap))))
- ;; There is a gap, lets see if we need to report it
- (unless (org-agenda-check-clock-gap tlend ts gapok)
- (setq issue (format "Clocking gap: %d minutes"
- (/ (- ts tlend) 60))
- face (or (plist-get pl :gap-face) face))))
- (t nil)))
- (setq tlend (or te tlend) tlstart (or ts tlstart))
- (when issue
- ;; OK, there was some issue, add an overlay to show the issue
- (setq ov (make-overlay (point-at-bol) (point-at-eol)))
- (overlay-put ov 'before-string
- (concat
- (org-add-props
- (format "%-43s" (concat " " issue))
- nil
- 'face face)
- "\n"))
- (overlay-put ov 'evaporate t)))))
-
-(defun org-agenda-check-clock-gap (t1 t2 ok-list)
- "Check if gap T1 -> T2 contains one of the OK-LIST time-of-day values."
- (catch 'exit
- (unless ok-list
- ;; there are no OK times for gaps...
- (throw 'exit nil))
- (when (> (- (/ t2 36000) (/ t1 36000)) 24)
- ;; This is more than 24 hours, so it is OK.
- ;; because we have at least one OK time, that must be in the
- ;; 24 hour interval.
- (throw 'exit t))
- ;; We have a shorter gap.
- ;; Now we have to get the minute of the day when these times are
- (let* ((t1dec (org-decode-time t1))
- (t2dec (org-decode-time t2))
- ;; compute the minute on the day
- (min1 (+ (nth 1 t1dec) (* 60 (nth 2 t1dec))))
- (min2 (+ (nth 1 t2dec) (* 60 (nth 2 t2dec)))))
- (when (< min2 min1)
- ;; if min2 is smaller than min1, this means it is on the next day.
- ;; Wrap it to after midnight.
- (setq min2 (+ min2 1440)))
- ;; Now check if any of the OK times is in the gap
- (mapc (lambda (x)
- ;; Wrap the time to after midnight if necessary
- (when (< x min1) (setq x (+ x 1440)))
- ;; Check if in interval
- (and (<= min1 x) (>= min2 x) (throw 'exit t)))
- ok-list)
- ;; Nope, this gap is not OK
- nil)))
-
-(defun org-agenda-get-deadlines (&optional with-hour)
- "Return the deadline information for agenda display.
-When WITH-HOUR is non-nil, only return deadlines with an hour
-specification like [h]h:mm."
- (with-no-warnings (defvar date))
- (let* ((props (list 'mouse-face 'highlight
- 'org-not-done-regexp org-not-done-regexp
- 'org-todo-regexp org-todo-regexp
- 'org-complex-heading-regexp org-complex-heading-regexp
- 'help-echo
- (format "mouse-2 or RET jump to org file %s"
- (abbreviate-file-name buffer-file-name))))
- (regexp (if with-hour
- org-deadline-time-hour-regexp
- org-deadline-time-regexp))
- (today (org-today))
- (today? (org-agenda-today-p date)) ; DATE bound by calendar.
- (current (calendar-absolute-from-gregorian date))
- deadline-items)
- (goto-char (point-min))
- (while (re-search-forward regexp nil t)
- (catch :skip
- (unless (save-match-data (org-at-planning-p)) (throw :skip nil))
- (org-agenda-skip)
- (let* ((s (match-string 1))
- (pos (1- (match-beginning 1)))
- (todo-state (save-match-data (org-get-todo-state)))
- (done? (member todo-state org-done-keywords))
- (sexp? (string-prefix-p "%%" s))
- ;; DEADLINE is the deadline date for the entry. It is
- ;; either the base date or the last repeat, according
- ;; to `org-agenda-prefer-last-repeat'.
- (deadline
- (cond
- (sexp? (org-agenda--timestamp-to-absolute s current))
- ((or (eq org-agenda-prefer-last-repeat t)
- (member todo-state org-agenda-prefer-last-repeat))
- (org-agenda--timestamp-to-absolute
- s today 'past (current-buffer) pos))
- (t (org-agenda--timestamp-to-absolute s))))
- ;; REPEAT is the future repeat closest from CURRENT,
- ;; according to `org-agenda-show-future-repeats'. If
- ;; the latter is nil, or if the time stamp has no
- ;; repeat part, default to DEADLINE.
- (repeat
- (cond
- (sexp? deadline)
- ((<= current today) deadline)
- ((not org-agenda-show-future-repeats) deadline)
- (t
- (let ((base (if (eq org-agenda-show-future-repeats 'next)
- (1+ today)
- current)))
- (org-agenda--timestamp-to-absolute
- s base 'future (current-buffer) pos)))))
- (diff (- deadline current))
- (suppress-prewarning
- (let ((scheduled
- (and org-agenda-skip-deadline-prewarning-if-scheduled
- (org-entry-get nil "SCHEDULED"))))
- (cond
- ((not scheduled) nil)
- ;; The current item has a scheduled date, so
- ;; evaluate its prewarning lead time.
- ((integerp org-agenda-skip-deadline-prewarning-if-scheduled)
- ;; Use global prewarning-restart lead time.
- org-agenda-skip-deadline-prewarning-if-scheduled)
- ((eq org-agenda-skip-deadline-prewarning-if-scheduled
- 'pre-scheduled)
- ;; Set pre-warning to no earlier than SCHEDULED.
- (min (- deadline
- (org-agenda--timestamp-to-absolute scheduled))
- org-deadline-warning-days))
- ;; Set pre-warning to deadline.
- (t 0))))
- (wdays (or suppress-prewarning (org-get-wdays s))))
- (cond
- ;; Only display deadlines at their base date, at future
- ;; repeat occurrences or in today agenda.
- ((= current deadline) nil)
- ((= current repeat) nil)
- ((not today?) (throw :skip nil))
- ;; Upcoming deadline: display within warning period WDAYS.
- ((> deadline current) (when (> diff wdays) (throw :skip nil)))
- ;; Overdue deadline: warn about it for
- ;; `org-deadline-past-days' duration.
- (t (when (< org-deadline-past-days (- diff)) (throw :skip nil))))
- ;; Possibly skip done tasks.
- (when (and done?
- (or org-agenda-skip-deadline-if-done
- (/= deadline current)))
- (throw :skip nil))
- (save-excursion
- (re-search-backward "^\\*+[ \t]+" nil t)
- (goto-char (match-end 0))
- (let* ((category (org-get-category))
- (level (make-string (org-reduced-level (org-outline-level))
- ?\s))
- (head (buffer-substring (point) (line-end-position)))
- (inherited-tags
- (or (eq org-agenda-show-inherited-tags 'always)
- (and (listp org-agenda-show-inherited-tags)
- (memq 'agenda org-agenda-show-inherited-tags))
- (and (eq org-agenda-show-inherited-tags t)
- (or (eq org-agenda-use-tag-inheritance t)
- (memq 'agenda
- org-agenda-use-tag-inheritance)))))
- (tags (org-get-tags nil (not inherited-tags)))
- (time
- (cond
- ;; No time of day designation if it is only
- ;; a reminder.
- ((and (/= current deadline) (/= current repeat)) nil)
- ((string-match " \\([012]?[0-9]:[0-9][0-9]\\)" s)
- (concat (substring s (match-beginning 1)) " "))
- (t 'time)))
- (item
- (org-agenda-format-item
- ;; Insert appropriate suffixes before deadlines.
- ;; Those only apply to today agenda.
- (pcase-let ((`(,now ,future ,past)
- org-agenda-deadline-leaders))
- (cond
- ((and today? (< deadline today)) (format past (- diff)))
- ((and today? (> deadline today)) (format future diff))
- (t now)))
- head level category tags time))
- (face (org-agenda-deadline-face
- (- 1 (/ (float diff) (max wdays 1)))))
- (upcoming? (and today? (> deadline today)))
- (warntime (get-text-property (point) 'org-appt-warntime)))
- (org-add-props item props
- 'org-marker (org-agenda-new-marker pos)
- 'org-hd-marker (org-agenda-new-marker (line-beginning-position))
- 'warntime warntime
- 'level level
- 'ts-date deadline
- 'priority
- ;; Adjust priority to today reminders about deadlines.
- ;; Overdue deadlines get the highest priority
- ;; increase, then imminent deadlines and eventually
- ;; more distant deadlines.
- (let ((adjust (if today? (- diff) 0)))
- (+ adjust (org-get-priority item)))
- 'todo-state todo-state
- 'type (if upcoming? "upcoming-deadline" "deadline")
- 'date (if upcoming? date deadline)
- 'face (if done? 'org-agenda-done face)
- 'undone-face face
- 'done-face 'org-agenda-done)
- (push item deadline-items))))))
- (nreverse deadline-items)))
-
-(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."
- (assoc-default fraction org-agenda-deadline-faces #'<=))
-
-(defun org-agenda-get-scheduled (&optional deadlines with-hour)
- "Return the scheduled information for agenda display.
-Optional argument DEADLINES is a list of deadline items to be
-displayed in agenda view. When WITH-HOUR is non-nil, only return
-scheduled items with an hour specification like [h]h:mm."
- (with-no-warnings (defvar date))
- (let* ((props (list 'org-not-done-regexp org-not-done-regexp
- 'org-todo-regexp org-todo-regexp
- 'org-complex-heading-regexp org-complex-heading-regexp
- 'done-face 'org-agenda-done
- 'mouse-face 'highlight
- 'help-echo
- (format "mouse-2 or RET jump to Org file %s"
- (abbreviate-file-name buffer-file-name))))
- (regexp (if with-hour
- org-scheduled-time-hour-regexp
- org-scheduled-time-regexp))
- (today (org-today))
- (todayp (org-agenda-today-p date)) ; DATE bound by calendar.
- (current (calendar-absolute-from-gregorian date))
- (deadline-pos
- (mapcar (lambda (d)
- (let ((m (get-text-property 0 'org-hd-marker d)))
- (and m (marker-position m))))
- deadlines))
- scheduled-items)
- (goto-char (point-min))
- (while (re-search-forward regexp nil t)
- (catch :skip
- (unless (save-match-data (org-at-planning-p)) (throw :skip nil))
- (org-agenda-skip)
- (let* ((s (match-string 1))
- (pos (1- (match-beginning 1)))
- (todo-state (save-match-data (org-get-todo-state)))
- (donep (member todo-state org-done-keywords))
- (sexp? (string-prefix-p "%%" s))
- ;; SCHEDULE is the scheduled date for the entry. It is
- ;; either the bare date or the last repeat, according
- ;; to `org-agenda-prefer-last-repeat'.
- (schedule
- (cond
- (sexp? (org-agenda--timestamp-to-absolute s current))
- ((or (eq org-agenda-prefer-last-repeat t)
- (member todo-state org-agenda-prefer-last-repeat))
- (org-agenda--timestamp-to-absolute
- s today 'past (current-buffer) pos))
- (t (org-agenda--timestamp-to-absolute s))))
- ;; REPEAT is the future repeat closest from CURRENT,
- ;; according to `org-agenda-show-future-repeats'. If
- ;; the latter is nil, or if the time stamp has no
- ;; repeat part, default to SCHEDULE.
- (repeat
- (cond
- (sexp? schedule)
- ((<= current today) schedule)
- ((not org-agenda-show-future-repeats) schedule)
- (t
- (let ((base (if (eq org-agenda-show-future-repeats 'next)
- (1+ today)
- current)))
- (org-agenda--timestamp-to-absolute
- s base 'future (current-buffer) pos)))))
- (diff (- current schedule))
- (warntime (get-text-property (point) 'org-appt-warntime))
- (pastschedp (< schedule today))
- (futureschedp (> schedule today))
- (habitp (and (fboundp 'org-is-habit-p) (org-is-habit-p)))
- (suppress-delay
- (let ((deadline (and org-agenda-skip-scheduled-delay-if-deadline
- (org-entry-get nil "DEADLINE"))))
- (cond
- ((not deadline) nil)
- ;; The current item has a deadline date, so
- ;; evaluate its delay time.
- ((integerp org-agenda-skip-scheduled-delay-if-deadline)
- ;; Use global delay time.
- (- org-agenda-skip-scheduled-delay-if-deadline))
- ((eq org-agenda-skip-scheduled-delay-if-deadline
- 'post-deadline)
- ;; Set delay to no later than DEADLINE.
- (min (- schedule
- (org-agenda--timestamp-to-absolute deadline))
- org-scheduled-delay-days))
- (t 0))))
- (ddays
- (cond
- ;; Nullify delay when a repeater triggered already
- ;; and the delay is of the form --Xd.
- ((and (string-match-p "--[0-9]+[hdwmy]" s)
- (> schedule (org-agenda--timestamp-to-absolute s)))
- 0)
- (suppress-delay
- (let ((org-scheduled-delay-days suppress-delay))
- (org-get-wdays s t t)))
- (t (org-get-wdays s t)))))
- ;; Display scheduled items at base date (SCHEDULE), today if
- ;; scheduled before the current date, and at any repeat past
- ;; today. However, skip delayed items and items that have
- ;; been displayed for more than `org-scheduled-past-days'.
- (unless (and todayp
- habitp
- (bound-and-true-p org-habit-show-all-today))
- (when (or (and (> ddays 0) (< diff ddays))
- (> diff (or (and habitp org-habit-scheduled-past-days)
- org-scheduled-past-days))
- (> schedule current)
- (and (/= current schedule)
- (/= current today)
- (/= current repeat)))
- (throw :skip nil)))
- ;; Possibly skip done tasks.
- (when (and donep
- (or org-agenda-skip-scheduled-if-done
- (/= schedule current)))
- (throw :skip nil))
- ;; Skip entry if it already appears as a deadline, per
- ;; `org-agenda-skip-scheduled-if-deadline-is-shown'. This
- ;; doesn't apply to habits.
- (when (pcase org-agenda-skip-scheduled-if-deadline-is-shown
- ((guard
- (or (not (memq (line-beginning-position 0) deadline-pos))
- habitp))
- nil)
- (`repeated-after-deadline
- (let ((deadline (time-to-days
- (org-get-deadline-time (point)))))
- (and (<= schedule deadline) (> current deadline))))
- (`not-today pastschedp)
- (`t t)
- (_ nil))
- (throw :skip nil))
- ;; Skip habits if `org-habit-show-habits' is nil, or if we
- ;; only show them for today. Also skip done habits.
- (when (and habitp
- (or donep
- (not (bound-and-true-p org-habit-show-habits))
- (and (not todayp)
- (bound-and-true-p
- org-habit-show-habits-only-for-today))))
- (throw :skip nil))
- (save-excursion
- (re-search-backward "^\\*+[ \t]+" nil t)
- (goto-char (match-end 0))
- (let* ((category (org-get-category))
- (inherited-tags
- (or (eq org-agenda-show-inherited-tags 'always)
- (and (listp org-agenda-show-inherited-tags)
- (memq 'agenda org-agenda-show-inherited-tags))
- (and (eq org-agenda-show-inherited-tags t)
- (or (eq org-agenda-use-tag-inheritance t)
- (memq 'agenda
- org-agenda-use-tag-inheritance)))))
- (tags (org-get-tags nil (not inherited-tags)))
- (level (make-string (org-reduced-level (org-outline-level))
- ?\s))
- (head (buffer-substring (point) (line-end-position)))
- (time
- (cond
- ;; No time of day designation if it is only a
- ;; reminder, except for habits, which always show
- ;; the time of day. Habits are an exception
- ;; because if there is a time of day, that is
- ;; interpreted to mean they should usually happen
- ;; then, even if doing the habit was missed.
- ((and
- (not habitp)
- (/= current schedule)
- (/= current repeat))
- nil)
- ((string-match " \\([012]?[0-9]:[0-9][0-9]\\)" s)
- (concat (substring s (match-beginning 1)) " "))
- (t 'time)))
- (item
- (org-agenda-format-item
- (pcase-let ((`(,first ,past) org-agenda-scheduled-leaders))
- ;; Show a reminder of a past scheduled today.
- (if (and todayp pastschedp)
- (format past diff)
- first))
- head level category tags time nil habitp))
- (face (cond ((and (not habitp) pastschedp)
- 'org-scheduled-previously)
- ((and habitp futureschedp)
- 'org-agenda-done)
- (todayp 'org-scheduled-today)
- (t 'org-scheduled)))
- (habitp (and habitp (org-habit-parse-todo))))
- (org-add-props item props
- 'undone-face face
- 'face (if donep 'org-agenda-done face)
- 'org-marker (org-agenda-new-marker pos)
- 'org-hd-marker (org-agenda-new-marker (line-beginning-position))
- 'type (if pastschedp "past-scheduled" "scheduled")
- 'date (if pastschedp schedule date)
- 'ts-date schedule
- 'warntime warntime
- 'level level
- 'priority (if habitp (org-habit-get-priority habitp)
- (+ 99 diff (org-get-priority item)))
- 'org-habit-p habitp
- 'todo-state todo-state)
- (push item scheduled-items))))))
- (nreverse scheduled-items)))
-
-(defun org-agenda-get-blocks ()
- "Return the date-range information for agenda display."
- (with-no-warnings (defvar date))
- (let* ((props (list 'face nil
- 'org-not-done-regexp org-not-done-regexp
- 'org-todo-regexp org-todo-regexp
- 'org-complex-heading-regexp org-complex-heading-regexp
- 'mouse-face 'highlight
- 'help-echo
- (format "mouse-2 or RET jump to org file %s"
- (abbreviate-file-name buffer-file-name))))
- (regexp org-tr-regexp)
- (d0 (calendar-absolute-from-gregorian date))
- marker hdmarker ee txt d1 d2 s1 s2 category
- level todo-state tags pos head donep inherited-tags)
- (goto-char (point-min))
- (while (re-search-forward regexp nil t)
- (catch :skip
- (org-agenda-skip)
- (setq pos (point))
- (let ((start-time (match-string 1))
- (end-time (match-string 2)))
- (setq s1 (match-string 1)
- s2 (match-string 2)
- d1 (time-to-days
- (condition-case err
- (org-time-string-to-time s1)
- (error
- (error
- "Bad timestamp %S at %d in buffer %S\nError was: %s"
- s1
- pos
- (current-buffer)
- (error-message-string err)))))
- d2 (time-to-days
- (condition-case err
- (org-time-string-to-time s2)
- (error
- (error
- "Bad timestamp %S at %d in buffer %S\nError was: %s"
- s2
- pos
- (current-buffer)
- (error-message-string err))))))
- (when (and (> (- d0 d1) -1) (> (- d2 d0) -1))
- ;; Only allow days between the limits, because the normal
- ;; date stamps will catch the limits.
- (save-excursion
- (setq todo-state (org-get-todo-state))
- (setq donep (member todo-state org-done-keywords))
- (when (and donep org-agenda-skip-timestamp-if-done)
- (throw :skip t))
- (setq marker (org-agenda-new-marker (point))
- category (org-get-category))
- (if (not (re-search-backward org-outline-regexp-bol nil t))
- (throw :skip nil)
- (goto-char (match-beginning 0))
- (setq hdmarker (org-agenda-new-marker (point))
- inherited-tags
- (or (eq org-agenda-show-inherited-tags 'always)
- (and (listp org-agenda-show-inherited-tags)
- (memq 'agenda org-agenda-show-inherited-tags))
- (and (eq org-agenda-show-inherited-tags t)
- (or (eq org-agenda-use-tag-inheritance t)
- (memq 'agenda org-agenda-use-tag-inheritance))))
- tags (org-get-tags nil (not inherited-tags)))
- (setq level (make-string (org-reduced-level (org-outline-level)) ? ))
- (looking-at "\\*+[ \t]+\\(.*\\)")
- (setq head (match-string 1))
- (let ((remove-re
- (if org-agenda-remove-timeranges-from-blocks
- (concat
- "<" (regexp-quote s1) ".*?>"
- "--"
- "<" (regexp-quote s2) ".*?>")
- nil)))
- (setq txt (org-agenda-format-item
- (format
- (nth (if (= d1 d2) 0 1)
- org-agenda-timerange-leaders)
- (1+ (- d0 d1)) (1+ (- d2 d1)))
- head level category tags
- (save-match-data
- (let ((hhmm1 (and (string-match org-ts-regexp1 s1)
- (match-string 6 s1)))
- (hhmm2 (and (string-match org-ts-regexp1 s2)
- (match-string 6 s2))))
- (cond ((string= hhmm1 hhmm2)
- (concat "<" start-time ">--<" end-time ">"))
- ((and (= d1 d0) (= d2 d0))
- (concat "<" start-time ">--<" end-time ">"))
- ((= d1 d0)
- (concat "<" start-time ">"))
- ((= d2 d0)
- (concat "<" end-time ">")))))
- remove-re))))
- (org-add-props txt props
- 'org-marker marker 'org-hd-marker hdmarker
- 'type "block" 'date date
- 'level level
- 'todo-state todo-state
- 'priority (org-get-priority txt))
- (push txt ee))))
- (goto-char pos)))
- ;; Sort the entries by expiration date.
- (nreverse ee)))
-
-;;; Agenda presentation and sorting
-
-(defvar org-prefix-has-time nil
- "A flag, set by `org-compile-prefix-format'.
-The flag is set if the currently compiled format contains a `%t'.")
-(defvar org-prefix-has-tag nil
- "A flag, set by `org-compile-prefix-format'.
-The flag is set if the currently compiled format contains a `%T'.")
-(defvar org-prefix-has-effort nil
- "A flag, set by `org-compile-prefix-format'.
-The flag is set if the currently compiled format contains a `%e'.")
-(defvar org-prefix-has-breadcrumbs nil
- "A flag, set by `org-compile-prefix-format'.
-The flag is set if the currently compiled format contains a `%b'.")
-(defvar org-prefix-category-length nil
- "Used by `org-compile-prefix-format' to remember the category field width.")
-(defvar org-prefix-category-max-length nil
- "Used by `org-compile-prefix-format' to remember the category field width.")
-
-(defun org-agenda-get-category-icon (category)
- "Return an image for CATEGORY according to `org-agenda-category-icon-alist'."
- (cl-dolist (entry org-agenda-category-icon-alist)
- (when (string-match-p (car entry) category)
- (if (listp (cadr entry))
- (cl-return (cadr entry))
- (cl-return (apply #'create-image (cdr entry)))))))
-
-(defun org-agenda-format-item (extra txt &optional with-level with-category tags dotime
- remove-re habitp)
- "Format TXT to be inserted into the agenda buffer.
-In particular, add the prefix and corresponding text properties.
-
-EXTRA must be a string to replace the `%s' specifier in the prefix format.
-WITH-LEVEL may be a string to replace the `%l' specifier.
-WITH-CATEGORY (a string, a symbol or nil) may be used to overrule the default
-category taken from local variable or file name. It will replace the `%c'
-specifier in the format.
-DOTIME, when non-nil, indicates that a time-of-day should be extracted from
-TXT for sorting of this entry, and for the `%t' specifier in the format.
-When DOTIME is a string, this string is searched for a time before TXT is.
-TAGS can be the tags of the headline.
-Any match of REMOVE-RE will be removed from TXT."
- ;; We keep the org-prefix-* variable values along with a compiled
- ;; formatter, so that multiple agendas existing at the same time do
- ;; not step on each other toes.
- ;;
- ;; It was inconvenient to make these variables buffer local in
- ;; Agenda buffers, because this function expects to be called with
- ;; the buffer where item comes from being current, and not agenda
- ;; buffer
- (let* ((bindings (car org-prefix-format-compiled))
- (formatter (cadr org-prefix-format-compiled)))
- (cl-loop for (var value) in bindings
- do (set var value))
- (save-match-data
- ;; Diary entries sometimes have extra whitespace at the beginning
- (setq txt (org-trim txt))
-
- ;; Fix the tags part in txt
- (setq txt (org-agenda-fix-displayed-tags
- txt tags
- org-agenda-show-inherited-tags
- org-agenda-hide-tags-regexp))
-
- (with-no-warnings
- ;; `time', `tag', `effort' are needed for the eval of the prefix format.
- ;; Based on what I see in `org-compile-prefix-format', I added
- ;; a few more.
- (defvar breadcrumbs) (defvar category) (defvar category-icon)
- (defvar effort) (defvar extra)
- (defvar level) (defvar tag) (defvar time))
- (let* ((category (or with-category
- (if buffer-file-name
- (file-name-sans-extension
- (file-name-nondirectory buffer-file-name))
- "")))
- (category-icon (org-agenda-get-category-icon category))
- (category-icon (if category-icon
- (propertize " " 'display category-icon)
- ""))
- (effort (and (not (string= txt ""))
- (get-text-property 1 'effort txt)))
- (tag (if tags (nth (1- (length tags)) tags) ""))
- (time-grid-trailing-characters (nth 2 org-agenda-time-grid))
- (extra (or (and (not habitp) extra) ""))
- time
- (ts (when dotime (concat
- (if (stringp dotime) dotime "")
- (and org-agenda-search-headline-for-time txt))))
- (time-of-day (and dotime (org-get-time-of-day ts)))
- stamp plain s0 s1 s2 rtn srp l
- duration breadcrumbs)
- (and (derived-mode-p '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
- (when (or (setq stamp (string-match org-stamp-time-of-day-regexp ts))
- (setq plain (string-match org-plain-time-of-day-regexp ts)))
- (setq s0 (match-string 0 ts)
- srp (and stamp (match-end 3))
- s1 (match-string (if plain 1 2) ts)
- s2 (match-string (if plain 8 (if srp 4 6)) ts))
-
- ;; If the times are in TXT (not in DOTIMES), and the prefix will list
- ;; them, we might want to remove them there to avoid duplication.
- ;; The user can turn this off with a variable.
- (when (and org-prefix-has-time
- org-agenda-remove-times-when-in-prefix (or stamp plain)
- (string-match (concat (regexp-quote s0) " *") txt)
- (not (equal ?\] (string-to-char (substring txt (match-end 0)))))
- (if (eq org-agenda-remove-times-when-in-prefix 'beg)
- (= (match-beginning 0) 0)
- t))
- (setq txt (replace-match "" nil nil txt))))
- ;; Normalize the time(s) to 24 hour.
- (when s1 (setq s1 (org-get-time-of-day s1 t)))
- (when s2 (setq s2 (org-get-time-of-day s2 t)))
- ;; Try to set s2 if s1 and
- ;; `org-agenda-default-appointment-duration' are set
- (when (and s1 (not s2) org-agenda-default-appointment-duration)
- (setq s2
- (org-duration-from-minutes
- (+ (org-duration-to-minutes s1 t)
- org-agenda-default-appointment-duration)
- nil t)))
- ;; Compute the duration
- (when s2
- (setq duration (- (org-duration-to-minutes s2)
- (org-duration-to-minutes s1))))
- ;; Format S1 and S2 for display.
- (when s1 (setq s1 (format "%5s" (org-get-time-of-day s1 'overtime))))
- (when s2 (setq s2 (org-get-time-of-day s2 'overtime))))
- (when (string-match org-tag-group-re txt)
- ;; Tags are in the string
- (if (or (eq org-agenda-remove-tags t)
- (and org-agenda-remove-tags
- org-prefix-has-tag))
- (setq txt (replace-match "" t t txt))
- (setq txt (replace-match
- (concat (make-string (max (- 50 (length txt)) 1) ?\ )
- (match-string 1 txt))
- t t txt))))
-
- (when remove-re
- (while (string-match remove-re txt)
- (setq txt (replace-match "" t t txt))))
-
- ;; Set org-heading property on `txt' to mark the start of the
- ;; heading.
- (add-text-properties 0 (length txt) '(org-heading t) txt)
-
- ;; Prepare the variables needed in the eval of the compiled format
- (when org-prefix-has-breadcrumbs
- (setq breadcrumbs (org-with-point-at (org-get-at-bol 'org-marker)
- (let ((s (org-format-outline-path (org-get-outline-path)
- (1- (frame-width))
- nil org-agenda-breadcrumbs-separator)))
- (if (eq "" s) "" (concat s org-agenda-breadcrumbs-separator))))))
- (setq time (cond (s2 (concat
- (org-agenda-time-of-day-to-ampm-maybe s1)
- "-" (org-agenda-time-of-day-to-ampm-maybe s2)
- (when org-agenda-timegrid-use-ampm " ")))
- (s1 (concat
- (org-agenda-time-of-day-to-ampm-maybe s1)
- (if org-agenda-timegrid-use-ampm
- (concat time-grid-trailing-characters " ")
- time-grid-trailing-characters)))
- (t ""))
- category (if (symbolp category) (symbol-name category) category)
- level (or with-level ""))
- (if (string-match org-link-bracket-re category)
- (progn
- (setq l (string-width (or (match-string 2) (match-string 1))))
- (when (< l (or org-prefix-category-length 0))
- (setq category (copy-sequence category))
- (org-add-props category nil
- 'extra-space (make-string
- (- org-prefix-category-length l 1) ?\ ))))
- (when (and org-prefix-category-max-length
- (>= (length category) org-prefix-category-max-length))
- (setq category (substring category 0 (1- org-prefix-category-max-length)))))
- ;; Evaluate the compiled format
- (setq rtn (concat (eval formatter t) txt))
-
- ;; And finally add the text properties
- (remove-text-properties 0 (length rtn) '(line-prefix t wrap-prefix t) rtn)
- (org-add-props rtn nil
- 'org-category category
- 'tags tags
- 'org-priority-highest org-priority-highest
- 'org-priority-lowest org-priority-lowest
- 'time-of-day time-of-day
- 'duration duration
- 'breadcrumbs breadcrumbs
- 'txt txt
- 'level level
- 'time time
- 'extra extra
- 'format org-prefix-format-compiled
- 'dotime dotime)))))
-
-(defun org-agenda-fix-displayed-tags (txt tags add-inherited hide-re)
- "Remove tags string from TXT, and add a modified list of tags.
-The modified list may contain inherited tags, and tags matched by
-`org-agenda-hide-tags-regexp' will be removed."
- (when (or add-inherited hide-re)
- (when (string-match org-tag-group-re txt)
- (setq txt (substring txt 0 (match-beginning 0))))
- (setq tags
- (delq nil
- (mapcar (lambda (tg)
- (if (or (and hide-re (string-match hide-re tg))
- (and (not add-inherited)
- (get-text-property 0 'inherited tg)))
- nil
- tg))
- tags)))
- (when tags
- (let ((have-i (get-text-property 0 'inherited (car tags)))
- i)
- (setq txt (concat txt " :"
- (mapconcat
- (lambda (x)
- (setq i (get-text-property 0 'inherited x))
- (if (and have-i (not i))
- (progn
- (setq have-i nil)
- (concat ":" x))
- x))
- tags ":")
- (if have-i "::" ":"))))))
- txt)
-
-(defvar org-agenda-sorting-strategy) ;; because the def is in a let form
-
-(defun org-agenda-add-time-grid-maybe (list ndays todayp)
- "Add a time-grid for agenda items which need it.
-
-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."
- (catch 'exit
- (cond ((not org-agenda-use-time-grid) (throw 'exit list))
- ((and todayp (member 'today (car org-agenda-time-grid))))
- ((and (= ndays 1) (member 'daily (car org-agenda-time-grid))))
- ((member 'weekly (car org-agenda-time-grid)))
- (t (throw 'exit list)))
- (let* ((have (delq nil (mapcar
- (lambda (x) (get-text-property 1 'time-of-day x))
- list)))
- (string (nth 3 org-agenda-time-grid))
- (gridtimes (nth 1 org-agenda-time-grid))
- (req (car org-agenda-time-grid))
- (remove (member 'remove-match req))
- new time)
- (when (and (member 'require-timed req) (not have))
- ;; don't show empty grid
- (throw 'exit list))
- (while (setq time (pop gridtimes))
- (unless (and remove (member time have))
- (setq time (replace-regexp-in-string " " "0" (format "%04s" time)))
- (push (org-agenda-format-item
- nil string nil "" nil
- (concat (substring time 0 -2) ":" (substring time -2)))
- new)
- (put-text-property
- 2 (length (car new)) 'face 'org-time-grid (car new))))
- (when (and todayp org-agenda-show-current-time-in-grid)
- (push (org-agenda-format-item
- nil org-agenda-current-time-string nil "" nil
- (format-time-string "%H:%M "))
- new)
- (put-text-property
- 2 (length (car new)) 'face 'org-agenda-current-time (car new)))
-
- (if (member 'time-up org-agenda-sorting-strategy-selected)
- (append new list)
- (append list new)))))
-
-(defun org-compile-prefix-format (key)
- "Compile the prefix format into a Lisp form that can be evaluated.
-The resulting form and associated variable bindings 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-has-breadcrumbs nil)
- (let ((s (cond
- ((stringp org-agenda-prefix-format)
- org-agenda-prefix-format)
- ((assq key org-agenda-prefix-format)
- (cdr (assq key org-agenda-prefix-format)))
- (t " %-12:c%?-12t% s")))
- (start 0)
- varform vars var c f opt) ;; e
- (while (string-match "%\\(\\?\\)?\\([-+]?[0-9.]*\\)\\([ .;,:!?=|/<>]?\\)\\([cltseib]\\|(.+?)\\)"
- s start)
- (setq var (or (cdr (assoc (match-string 4 s)
- '(("c" . category) ("t" . time) ("l" . level) ("s" . extra)
- ("i" . category-icon) ("T" . tag) ("e" . effort) ("b" . breadcrumbs))))
- 'eval)
- c (or (match-string 3 s) "")
- opt (match-beginning 1)
- start (1+ (match-beginning 0)))
- (cl-case var
- (time (setq org-prefix-has-time t))
- (tag (setq org-prefix-has-tag t))
- (effort (setq org-prefix-has-effort t))
- (breadcrumbs (setq org-prefix-has-breadcrumbs t)))
- (setq f (concat "%" (match-string 2 s) "s"))
- (when (eq var 'category)
- (setq org-prefix-category-length
- (floor (abs (string-to-number (match-string 2 s)))))
- (setq org-prefix-category-max-length
- (let ((x (match-string 2 s)))
- (save-match-data
- (and (string-match "\\.[0-9]+" x)
- (string-to-number (substring (match-string 0 x) 1)))))))
- (if (eq var 'eval)
- (setq varform `(format ,f (org-eval ,(read (substring s (match-beginning 4))))))
- (if opt
- (setq varform
- `(if (member ,var '("" nil))
- ""
- (format ,f (concat ,var ,c))))
- (setq varform
- `(format ,f (if (member ,var '("" nil)) ""
- (concat ,var ,c (get-text-property 0 'extra-space ,var)))))))
- (if (eq var 'eval)
- (setf (substring s (match-beginning 0)
- (+ (match-beginning 4)
- (length (format "%S" (read (substring s (match-beginning 4)))))))
- "%s")
- (setq s (replace-match "%s" t nil s)))
- (push varform vars))
- (setq vars (nreverse vars))
- (with-current-buffer (or org-agenda-buffer (current-buffer))
- (setq org-prefix-format-compiled
- (list
- `((org-prefix-has-time ,org-prefix-has-time)
- (org-prefix-has-tag ,org-prefix-has-tag)
- (org-prefix-category-length ,org-prefix-category-length)
- (org-prefix-has-effort ,org-prefix-has-effort)
- (org-prefix-has-breadcrumbs ,org-prefix-has-breadcrumbs))
- `(format ,s ,@vars))))))
-
-(defun org-set-sorting-strategy (key)
- (setq org-agenda-sorting-strategy-selected
- (if (symbolp (car org-agenda-sorting-strategy))
- ;; the old format
- org-agenda-sorting-strategy
- (or (cdr (assq key org-agenda-sorting-strategy))
- (cdr (assq 'agenda org-agenda-sorting-strategy))
- '(time-up category-keep priority-down)))))
-
-(defun org-get-time-of-day (s &optional string)
- "Check string S for a time of day.
-
-If found, return it as a military time number between 0 and 2400.
-If not found, return nil.
-
-The optional STRING argument forces conversion into a 5 character wide string
-HH:MM. When it is `overtime', any time above 24:00 is turned into \"+H:MM\"
-where H:MM is the duration above midnight."
- (let ((case-fold-search t)
- (time-regexp
- (rx word-start
- (group (opt (any "012")) digit) ;group 1: hours
- (or (and ":" (group (any "012345") digit) ;group 2: minutes
- (opt (group (or "am" "pm")))) ;group 3: am/pm
- ;; Special "HHam/pm" case.
- (group-n 3 (or "am" "pm")))
- word-end)))
- (save-match-data
- (when (and (string-match time-regexp s)
- (not (eq 'org-link (get-text-property 1 'face s))))
- (let ((hours
- (let* ((ampm (and (match-end 3) (downcase (match-string 3 s))))
- (am-p (equal ampm "am")))
- (pcase (string-to-number (match-string 1 s))
- ((and (guard (not ampm)) h) h)
- (12 (if am-p 0 12))
- (h (+ h (if am-p 0 12))))))
- (minutes
- (if (match-end 2)
- (string-to-number (match-string 2 s))
- 0)))
- (pcase string
- (`nil (+ minutes (* hours 100)))
- ((and `overtime
- (guard (or (> hours 24)
- (and (= hours 24)
- (> minutes 0)))))
- (format "+%d:%02d" (- hours 24) minutes))
- ((guard org-agenda-time-leading-zero)
- (format "%02d:%02d" hours minutes))
- (_
- (format "%d:%02d" hours minutes))))))))
-
-(defvar org-agenda-before-sorting-filter-function nil
- "Function to be applied to agenda items prior to sorting.
-Prior to sorting also means just before they are inserted into the agenda.
-
-To aid sorting, you may revisit the original entries and add more text
-properties which will later be used by the sorting functions.
-
-The function should take a string argument, an agenda line.
-It has access to the text properties in that line, which contain among
-other things, the property `org-hd-marker' that points to the entry
-where the line comes from. Note that not all lines going into the agenda
-have this property, only most.
-
-The function should return the modified string. It is probably best
-to ONLY change text properties.
-
-You can also use this function as a filter, by returning nil for lines
-you don't want to have in the agenda at all. For this application, you
-could bind the variable in the options section of a custom command.")
-
-(defun org-agenda-finalize-entries (list &optional type)
- "Sort, limit and concatenate the LIST of agenda items.
-The optional argument TYPE tells the agenda type."
- (let ((max-effort (cond ((listp org-agenda-max-effort)
- (cdr (assoc type org-agenda-max-effort)))
- (t org-agenda-max-effort)))
- (max-todo (cond ((listp org-agenda-max-todos)
- (cdr (assoc type org-agenda-max-todos)))
- (t org-agenda-max-todos)))
- (max-tags (cond ((listp org-agenda-max-tags)
- (cdr (assoc type org-agenda-max-tags)))
- (t org-agenda-max-tags)))
- (max-entries (cond ((listp org-agenda-max-entries)
- (cdr (assoc type org-agenda-max-entries)))
- (t org-agenda-max-entries))))
- (when org-agenda-before-sorting-filter-function
- (setq list
- (delq nil
- (mapcar
- org-agenda-before-sorting-filter-function list))))
- (setq list (mapcar #'org-agenda-highlight-todo list)
- list (mapcar #'identity (sort list #'org-entries-lessp)))
- (when max-effort
- (setq list (org-agenda-limit-entries
- list 'effort-minutes max-effort
- (lambda (e) (or e (if org-agenda-sort-noeffort-is-high
- 32767 -1))))))
- (when max-todo
- (setq list (org-agenda-limit-entries list 'todo-state max-todo)))
- (when max-tags
- (setq list (org-agenda-limit-entries list 'tags max-tags)))
- (when max-entries
- (setq list (org-agenda-limit-entries list 'org-hd-marker max-entries)))
- (when (and org-agenda-dim-blocked-tasks org-blocker-hook)
- (setq list (mapcar #'org-agenda--mark-blocked-entry list)))
- (mapconcat #'identity list "\n")))
-
-(defun org-agenda-limit-entries (list prop limit &optional fn)
- "Limit the number of agenda entries."
- (let ((include (and limit (< limit 0))))
- (if limit
- (let ((fun (or fn (lambda (p) (when p 1))))
- (lim 0))
- (delq nil
- (mapcar
- (lambda (e)
- (let ((pval (funcall
- fun (get-text-property (1- (length e))
- prop e))))
- (when pval (setq lim (+ lim pval)))
- (cond ((and pval (<= lim (abs limit))) e)
- ((and include (not pval)) e))))
- list)))
- list)))
-
-(defun org-agenda-limit-interactively (remove)
- "In agenda, interactively limit entries to various maximums."
- (interactive "P")
- (if remove
- (progn (setq org-agenda-max-entries nil
- org-agenda-max-todos nil
- org-agenda-max-tags nil
- org-agenda-max-effort nil)
- (org-agenda-redo))
- (let* ((max (read-char "Number of [e]ntries [t]odos [T]ags [E]ffort? "))
- (msg (cond ((= max ?E) "How many minutes? ")
- ((= max ?e) "How many entries? ")
- ((= max ?t) "How many TODO entries? ")
- ((= max ?T) "How many tagged entries? ")
- (t (user-error "Wrong input"))))
- (num (string-to-number (read-from-minibuffer msg))))
- (cond ((equal max ?e)
- (let ((org-agenda-max-entries num)) (org-agenda-redo)))
- ((equal max ?t)
- (let ((org-agenda-max-todos num)) (org-agenda-redo)))
- ((equal max ?T)
- (let ((org-agenda-max-tags num)) (org-agenda-redo)))
- ((equal max ?E)
- (let ((org-agenda-max-effort num)) (org-agenda-redo))))))
- (org-agenda-fit-window-to-buffer))
-
-(defun org-agenda-highlight-todo (x)
- (let ((org-done-keywords org-done-keywords-for-agenda)
- (case-fold-search nil)
- re)
- (if (eq x 'line)
- (save-excursion
- (beginning-of-line 1)
- (setq re (org-get-at-bol 'org-todo-regexp))
- (goto-char (or (text-property-any (point-at-bol) (point-at-eol) 'org-heading t) (point)))
- (when (looking-at (concat "[ \t]*\\.*\\(" re "\\) +"))
- (add-text-properties (match-beginning 0) (match-end 1)
- (list 'face (org-get-todo-face 1)))
- (let ((s (buffer-substring (match-beginning 1) (match-end 1))))
- (delete-region (match-beginning 1) (1- (match-end 0)))
- (goto-char (match-beginning 1))
- (insert (format org-agenda-todo-keyword-format s)))))
- (let ((pl (text-property-any 0 (length x) 'org-heading t x)))
- (setq re (get-text-property 0 'org-todo-regexp x))
- (when (and re
- ;; Test `pl' because if there's no heading content,
- ;; there's no point matching to highlight. Note
- ;; that if we didn't test `pl' first, and there
- ;; happened to be no keyword from `org-todo-regexp'
- ;; on this heading line, then the `equal' comparison
- ;; afterwards would spuriously succeed in the case
- ;; where `pl' is nil -- causing an args-out-of-range
- ;; error when we try to add text properties to text
- ;; that isn't there.
- pl
- (equal (string-match (concat "\\(\\.*\\)" re "\\( +\\)")
- x pl)
- pl))
- (add-text-properties
- (or (match-end 1) (match-end 0)) (match-end 0)
- (list 'face (org-get-todo-face (match-string 2 x)))
- x)
- (when (match-end 1)
- (setq x
- (concat
- (substring x 0 (match-end 1))
- (unless (string= org-agenda-todo-keyword-format "")
- (format org-agenda-todo-keyword-format
- (match-string 2 x)))
- ;; Remove `display' property as the icon could leak
- ;; on the white space.
- (org-add-props " " (org-plist-delete (text-properties-at 0 x)
- 'display))
- (substring x (match-end 3)))))))
- x)))
-
-(defsubst org-cmp-values (a b property)
- "Compare the numeric value of text PROPERTY for string A and B."
- (let ((pa (or (get-text-property (1- (length a)) property a) 0))
- (pb (or (get-text-property (1- (length b)) property b) 0)))
- (cond ((> pa pb) +1)
- ((< pa pb) -1))))
-
-(defsubst org-cmp-effort (a b)
- "Compare the effort values of string A and B."
- (let* ((def (if org-agenda-sort-noeffort-is-high 32767 -1))
- ;; `effort-minutes' property is not directly accessible from
- ;; the strings, but is stored as a property in `txt'.
- (ea (or (get-text-property
- 0 'effort-minutes (get-text-property 0 'txt a))
- def))
- (eb (or (get-text-property
- 0 'effort-minutes (get-text-property 0 'txt b))
- def)))
- (cond ((> ea eb) +1)
- ((< ea eb) -1))))
-
-(defsubst org-cmp-category (a b)
- "Compare the string values of categories of strings A and B."
- (let ((ca (or (get-text-property (1- (length a)) 'org-category a) ""))
- (cb (or (get-text-property (1- (length b)) 'org-category b) "")))
- (cond ((string-lessp ca cb) -1)
- ((string-lessp cb ca) +1))))
-
-(defsubst org-cmp-todo-state (a b)
- "Compare the todo states of strings A and B."
- (let* ((ma (or (get-text-property 1 'org-marker a)
- (get-text-property 1 'org-hd-marker a)))
- (mb (or (get-text-property 1 'org-marker b)
- (get-text-property 1 'org-hd-marker b)))
- (fa (and ma (marker-buffer ma)))
- (fb (and mb (marker-buffer mb)))
- (todo-kwds
- (or (and fa (with-current-buffer fa org-todo-keywords-1))
- (and fb (with-current-buffer fb org-todo-keywords-1))))
- (ta (or (get-text-property 1 'todo-state a) ""))
- (tb (or (get-text-property 1 'todo-state b) ""))
- (la (- (length (member ta todo-kwds))))
- (lb (- (length (member tb todo-kwds))))
- (donepa (member ta org-done-keywords-for-agenda))
- (donepb (member tb org-done-keywords-for-agenda)))
- (cond ((and donepa (not donepb)) -1)
- ((and (not donepa) donepb) +1)
- ((< la lb) -1)
- ((< lb la) +1))))
-
-(defsubst org-cmp-alpha (a b)
- "Compare the headlines, alphabetically."
- (let* ((pla (text-property-any 0 (length a) 'org-heading t a))
- (plb (text-property-any 0 (length b) 'org-heading t b))
- (ta (and pla (substring a pla)))
- (tb (and plb (substring b plb)))
- (case-fold-search nil))
- (when pla
- (when (string-match (concat "\\`[ \t]*" (or (get-text-property 0 'org-todo-regexp a) "")
- "\\([ \t]*\\[[a-zA-Z0-9]\\]\\)? *")
- ta)
- (setq ta (substring ta (match-end 0))))
- (setq ta (downcase ta)))
- (when plb
- (when (string-match (concat "\\`[ \t]*" (or (get-text-property 0 'org-todo-regexp b) "")
- "\\([ \t]*\\[[a-zA-Z0-9]\\]\\)? *")
- tb)
- (setq tb (substring tb (match-end 0))))
- (setq tb (downcase tb)))
- (cond ((not (or ta tb)) nil)
- ((not ta) +1)
- ((not tb) -1)
- ((string-lessp ta tb) -1)
- ((string-lessp tb ta) +1))))
-
-(defsubst org-cmp-tag (a b)
- "Compare the string values of the first tags of A and B."
- (let ((ta (car (last (get-text-property 1 'tags a))))
- (tb (car (last (get-text-property 1 'tags b)))))
- (cond ((not (or ta tb)) nil)
- ((not ta) +1)
- ((not tb) -1)
- ((string-lessp ta tb) -1)
- ((string-lessp tb ta) +1))))
-
-(defsubst org-cmp-time (a b)
- "Compare the time-of-day values of strings A and B."
- (let* ((def (if org-agenda-sort-notime-is-late 9901 -1))
- (ta (or (get-text-property 1 'time-of-day a) def))
- (tb (or (get-text-property 1 'time-of-day b) def)))
- (cond ((< ta tb) -1)
- ((< tb ta) +1))))
-
-(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
-is the empty string, compare all timestamps without respect of
-their type."
- (let* ((def (and (not org-agenda-sort-notime-is-late) -1))
- (ta (or (and (string-match type (or (get-text-property 1 'type a) ""))
- (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)))
- (cond ((if ta (and tb (< ta tb)) tb) -1)
- ((if tb (and ta (< tb ta)) ta) +1))))
-
-(defsubst org-cmp-habit-p (a b)
- "Compare the todo states of strings A and B."
- (let ((ha (get-text-property 1 'org-habit-p a))
- (hb (get-text-property 1 'org-habit-p b)))
- (cond ((and ha (not hb)) -1)
- ((and (not ha) hb) +1))))
-
-(defun org-entries-lessp (a b)
- "Predicate for sorting agenda entries."
- ;; The following variables will be used when the form is evaluated.
- ;; So even though the compiler complains, keep them.
- (let ((ss org-agenda-sorting-strategy-selected))
- (org-dlet
- ((timestamp-up (and (org-em 'timestamp-up 'timestamp-down ss)
- (org-cmp-ts a b "")))
- (timestamp-down (if timestamp-up (- timestamp-up) nil))
- (scheduled-up (and (org-em 'scheduled-up 'scheduled-down ss)
- (org-cmp-ts a b "scheduled")))
- (scheduled-down (if scheduled-up (- scheduled-up) nil))
- (deadline-up (and (org-em 'deadline-up 'deadline-down ss)
- (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 "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")))
- (ts-down (if ts-up (- ts-up) nil))
- (time-up (and (org-em 'time-up 'time-down ss)
- (org-cmp-time a b)))
- (time-down (if time-up (- time-up) nil))
- (stats-up (and (org-em 'stats-up 'stats-down ss)
- (org-cmp-values a b 'org-stats)))
- (stats-down (if stats-up (- stats-up) nil))
- (priority-up (and (org-em 'priority-up 'priority-down ss)
- (org-cmp-values a b 'priority)))
- (priority-down (if priority-up (- priority-up) nil))
- (effort-up (and (org-em 'effort-up 'effort-down ss)
- (org-cmp-effort a b)))
- (effort-down (if effort-up (- effort-up) nil))
- (category-up (and (or (org-em 'category-up 'category-down ss)
- (memq 'category-keep ss))
- (org-cmp-category a b)))
- (category-down (if category-up (- category-up) nil))
- (category-keep (if category-up +1 nil))
- (tag-up (and (org-em 'tag-up 'tag-down ss)
- (org-cmp-tag a b)))
- (tag-down (if tag-up (- tag-up) nil))
- (todo-state-up (and (org-em 'todo-state-up 'todo-state-down ss)
- (org-cmp-todo-state a b)))
- (todo-state-down (if todo-state-up (- todo-state-up) nil))
- (habit-up (and (org-em 'habit-up 'habit-down ss)
- (org-cmp-habit-p a b)))
- (habit-down (if habit-up (- habit-up) nil))
- (alpha-up (and (org-em 'alpha-up 'alpha-down ss)
- (org-cmp-alpha a b)))
- (alpha-down (if alpha-up (- alpha-up) nil))
- (need-user-cmp (org-em 'user-defined-up 'user-defined-down ss))
- user-defined-up user-defined-down)
- (when (and need-user-cmp org-agenda-cmp-user-defined
- (functionp org-agenda-cmp-user-defined))
- (setq user-defined-up
- (funcall org-agenda-cmp-user-defined a b)
- user-defined-down (if user-defined-up (- user-defined-up) nil)))
- (cdr (assoc
- (eval (cons 'or org-agenda-sorting-strategy-selected) t)
- '((-1 . t) (1 . nil) (nil . nil)))))))
-
-;;; Agenda restriction lock
-
-(defvar org-agenda-restriction-lock-overlay (make-overlay 1 1)
- "Overlay to mark the headline to which agenda commands are restricted.")
-(overlay-put org-agenda-restriction-lock-overlay
- 'face 'org-agenda-restriction-lock)
-(overlay-put org-agenda-restriction-lock-overlay
- 'help-echo "Agendas are currently limited to this subtree.")
-(delete-overlay org-agenda-restriction-lock-overlay)
-
-(defun org-agenda-set-restriction-lock-from-agenda (arg)
- "Set the restriction lock to the agenda item at point from within the agenda.
-When called with a `\\[universal-argument]' prefix, restrict to
-the file which contains the item.
-Argument ARG is the prefix argument."
- (interactive "P")
- (unless (derived-mode-p 'org-agenda-mode)
- (user-error "Not in an Org agenda buffer"))
- (let* ((marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- (buffer (marker-buffer marker))
- (pos (marker-position marker)))
- (with-current-buffer buffer
- (goto-char pos)
- (org-agenda-set-restriction-lock arg))))
-
-;;;###autoload
-(defun org-agenda-set-restriction-lock (&optional type)
- "Set restriction lock for agenda to current subtree or file.
-When in a restricted subtree, remove it.
-
-The restriction will span over the entire file if TYPE is `file',
-or if type is '(4), or if the cursor is before the first headline
-in the file. Otherwise, only apply the restriction to the current
-subtree."
- (interactive "P")
- (if (and org-agenda-overriding-restriction
- (member org-agenda-restriction-lock-overlay
- (overlays-at (point)))
- (equal (overlay-start org-agenda-restriction-lock-overlay)
- (point)))
- (org-agenda-remove-restriction-lock 'noupdate)
- (org-agenda-remove-restriction-lock 'noupdate)
- (and (equal type '(4)) (setq type 'file))
- (setq type (cond
- (type type)
- ((org-at-heading-p) 'subtree)
- ((condition-case nil (org-back-to-heading t) (error nil))
- 'subtree)
- (t 'file)))
- (if (eq type 'subtree)
- (progn
- (setq org-agenda-restrict (current-buffer))
- (setq org-agenda-overriding-restriction 'subtree)
- (put 'org-agenda-files 'org-restrict
- (list (buffer-file-name (buffer-base-buffer))))
- (org-back-to-heading t)
- (move-overlay org-agenda-restriction-lock-overlay
- (point)
- (if org-agenda-restriction-lock-highlight-subtree
- (save-excursion (org-end-of-subtree t t) (point))
- (point-at-eol)))
- (move-marker org-agenda-restrict-begin (point))
- (move-marker org-agenda-restrict-end
- (save-excursion (org-end-of-subtree t t)))
- (message "Locking agenda restriction to subtree"))
- (put 'org-agenda-files 'org-restrict
- (list (buffer-file-name (buffer-base-buffer))))
- (setq org-agenda-restrict nil)
- (setq org-agenda-overriding-restriction 'file)
- (move-marker org-agenda-restrict-begin nil)
- (move-marker org-agenda-restrict-end nil)
- (message "Locking agenda restriction to file"))
- (setq current-prefix-arg nil))
- (org-agenda-maybe-redo))
-
-(defun org-agenda-remove-restriction-lock (&optional noupdate)
- "Remove agenda restriction lock."
- (interactive "P")
- (if (not org-agenda-restrict)
- (message "No agenda restriction to remove.")
- (delete-overlay org-agenda-restriction-lock-overlay)
- (delete-overlay org-speedbar-restriction-lock-overlay)
- (setq org-agenda-overriding-restriction nil)
- (setq org-agenda-restrict nil)
- (put 'org-agenda-files 'org-restrict nil)
- (move-marker org-agenda-restrict-begin nil)
- (move-marker org-agenda-restrict-end nil)
- (setq current-prefix-arg nil)
- (message "Agenda restriction lock removed")
- (or noupdate (org-agenda-maybe-redo))))
-
-(defun org-agenda-maybe-redo ()
- "If there is any window showing the agenda view, update it."
- (let ((w (get-buffer-window (or org-agenda-this-buffer-name
- org-agenda-buffer-name)
- t))
- (w0 (selected-window)))
- (when w
- (select-window w)
- (org-agenda-redo)
- (select-window w0)
- (if org-agenda-overriding-restriction
- (message "Agenda view shifted to new %s restriction"
- org-agenda-overriding-restriction)
- (message "Agenda restriction lock removed")))))
-
-;;; Agenda commands
-
-(defun org-agenda-check-type (error &rest types)
- "Check if agenda buffer or component is of allowed type.
-If ERROR is non-nil, throw an error, otherwise just return nil.
-Allowed types are `agenda' `todo' `tags' `search'."
- (cond ((not org-agenda-type)
- (error "No Org agenda currently displayed"))
- ((memq org-agenda-type types) t)
- (error
- (error "Not allowed in '%s'-type agenda buffer or component" org-agenda-type))
- (t nil)))
-
-(defun org-agenda-Quit ()
- "Exit the agenda, killing the agenda buffer.
-Like `org-agenda-quit', but kill the buffer even when
-`org-agenda-sticky' is non-nil."
- (interactive)
- (org-agenda--quit))
-
-(defun org-agenda-quit ()
- "Exit the agenda.
-
-When `org-agenda-sticky' is non-nil, bury the agenda buffer
-instead of killing it.
-
-When `org-agenda-restore-windows-after-quit' is non-nil, restore
-the pre-agenda window configuration.
-
-When column view is active, exit column view instead of the
-agenda."
- (interactive)
- (org-agenda--quit org-agenda-sticky))
-
-(defun org-agenda--quit (&optional bury)
- (if org-agenda-columns-active
- (org-columns-quit)
- (let ((wconf org-agenda-pre-window-conf)
- (buf (current-buffer))
- (org-agenda-last-indirect-window
- (and (eq org-indirect-buffer-display 'other-window)
- org-agenda-last-indirect-buffer
- (get-buffer-window org-agenda-last-indirect-buffer))))
- (cond
- ((eq org-agenda-window-setup 'other-frame)
- (delete-frame))
- ((eq org-agenda-window-setup 'other-tab)
- (if (fboundp 'tab-bar-close-tab)
- (tab-bar-close-tab)
- (user-error "Your version of Emacs does not have tab bar mode support")))
- ((and org-agenda-restore-windows-after-quit
- wconf)
- ;; Maybe restore the pre-agenda window configuration. Reset
- ;; `org-agenda-pre-window-conf' before running
- ;; `set-window-configuration', which loses the current buffer.
- (setq org-agenda-pre-window-conf nil)
- (set-window-configuration wconf))
- (t
- (when org-agenda-last-indirect-window
- (delete-window org-agenda-last-indirect-window))
- (and (not (eq org-agenda-window-setup 'current-window))
- (not (one-window-p))
- (delete-window))))
- (if bury
- ;; Set the agenda buffer as the current buffer instead of
- ;; passing it as an argument to `bury-buffer' so that
- ;; `bury-buffer' removes it from the window.
- (with-current-buffer buf
- (bury-buffer))
- (kill-buffer buf)
- (setq org-agenda-archives-mode nil
- org-agenda-buffer nil)))))
-
-(defun org-agenda-exit ()
- "Exit the agenda, killing Org buffers loaded by the agenda.
-Like `org-agenda-Quit', but kill any buffers that were created by
-the agenda. Org buffers visited directly by the user will not be
-touched. Also, exit the agenda even if it is in column view."
- (interactive)
- (when org-agenda-columns-active
- (org-columns-quit))
- (org-release-buffers org-agenda-new-buffers)
- (setq org-agenda-new-buffers nil)
- (org-agenda-Quit))
-
-(defun org-agenda-kill-all-agenda-buffers ()
- "Kill all buffers in `org-agenda-mode'.
-This is used when toggling sticky agendas."
- (interactive)
- (let (blist)
- (dolist (buf (buffer-list))
- (when (with-current-buffer buf (eq major-mode 'org-agenda-mode))
- (push buf blist)))
- (mapc #'kill-buffer blist)))
-
-(defun org-agenda-execute (arg)
- "Execute another agenda command, keeping same window.
-So this is just a shortcut for \\<global-map>`\\[org-agenda]', available
-in the agenda."
- (interactive "P")
- (let ((org-agenda-window-setup 'current-window))
- (org-agenda arg)))
-
-(defun org-agenda-redo (&optional all)
- "Rebuild possibly ALL agenda view(s) in the current buffer."
- (interactive "P")
- (defvar org-agenda-tag-filter-while-redo) ;FIXME: Where is this var used?
- (let* ((p (or (and (looking-at "\\'") (1- (point))) (point)))
- (cpa (unless (eq all t) current-prefix-arg))
- (org-agenda-doing-sticky-redo org-agenda-sticky)
- (org-agenda-sticky nil)
- (org-agenda-buffer-name (or org-agenda-this-buffer-name
- org-agenda-buffer-name))
- (org-agenda-keep-modes t)
- (tag-filter org-agenda-tag-filter)
- (tag-preset (get 'org-agenda-tag-filter :preset-filter))
- (top-hl-filter org-agenda-top-headline-filter)
- (cat-filter org-agenda-category-filter)
- (cat-preset (get 'org-agenda-category-filter :preset-filter))
- (re-filter org-agenda-regexp-filter)
- (re-preset (get 'org-agenda-regexp-filter :preset-filter))
- (effort-filter org-agenda-effort-filter)
- (effort-preset (get 'org-agenda-effort-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))))
- (lprops (get 'org-agenda-redo-command 'org-lprops))
- (redo-cmd (get-text-property p 'org-redo-cmd))
- (last-args (get-text-property p 'org-last-args))
- (org-agenda-overriding-cmd (get-text-property p 'org-series-cmd))
- (org-agenda-overriding-cmd-arguments
- (unless (eq all t)
- (cond ((listp last-args)
- (cons (or cpa (car last-args)) (cdr last-args)))
- ((stringp last-args)
- last-args))))
- (series-redo-cmd (get-text-property p 'org-series-redo-cmd)))
- (put 'org-agenda-tag-filter :preset-filter nil)
- (put 'org-agenda-category-filter :preset-filter nil)
- (put 'org-agenda-regexp-filter :preset-filter nil)
- (put 'org-agenda-effort-filter :preset-filter nil)
- (and cols (org-columns-quit))
- (message "Rebuilding agenda buffer...")
- (if series-redo-cmd
- (eval series-redo-cmd t)
- (cl-progv
- (mapcar #'car lprops)
- (mapcar (lambda (binding) (eval (cadr binding) t)) lprops)
- (eval redo-cmd t)))
- (setq org-agenda-undo-list nil
- org-agenda-pending-undo-list nil
- org-agenda-tag-filter tag-filter
- org-agenda-category-filter cat-filter
- org-agenda-regexp-filter re-filter
- org-agenda-effort-filter effort-filter
- org-agenda-top-headline-filter top-hl-filter)
- (message "Rebuilding agenda buffer...done")
- (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)
- (put 'org-agenda-effort-filter :preset-filter effort-preset)
- (let ((tag (or tag-filter tag-preset))
- (cat (or cat-filter cat-preset))
- (effort (or effort-filter effort-preset))
- (re (or re-filter re-preset)))
- (when tag (org-agenda-filter-apply tag 'tag t))
- (when cat (org-agenda-filter-apply cat 'category))
- (when effort (org-agenda-filter-apply effort 'effort))
- (when re (org-agenda-filter-apply re 'regexp)))
- (and top-hl-filter (org-agenda-filter-top-headline-apply top-hl-filter))
- (and cols (called-interactively-p 'any) (org-agenda-columns))
- (org-goto-line line)
- (when (called-interactively-p 'any) (recenter window-line))))
-
-(defun org-agenda-redo-all (&optional exhaustive)
- "Rebuild all agenda views in the current buffer.
-With a prefix argument, do so in all agenda buffers."
- (interactive "P")
- (if exhaustive
- (dolist (buffer (buffer-list))
- (with-current-buffer buffer
- (when (derived-mode-p 'org-agenda-mode)
- (org-agenda-redo t))))
- (org-agenda-redo t)))
-
-(defvar org-global-tags-completion-table nil)
-(defvar org-agenda-filter-form nil)
-(defvar org-agenda-filtered-by-category nil)
-
-(defsubst org-agenda-get-category ()
- "Return the category of the agenda line."
- (org-get-at-bol 'org-category))
-
-(defun org-agenda-filter-by-category (strip)
- "Filter lines in the agenda buffer that have a specific category.
-The category is that of the current line.
-With a `\\[universal-argument]' prefix argument, exclude the lines of that category.
-When there is already a category filter in place, this command removes the
-filter."
- (interactive "P")
- (if (and org-agenda-filtered-by-category
- org-agenda-category-filter)
- (org-agenda-filter-show-all-cat)
- (let ((cat (org-no-properties (org-get-at-eol 'org-category 1))))
- (cond
- ((and cat strip)
- (org-agenda-filter-apply
- (push (concat "-" cat) org-agenda-category-filter) 'category))
- (cat
- (org-agenda-filter-apply
- (setq org-agenda-category-filter
- (list (concat "+" cat)))
- 'category))
- (t (error "No category at point"))))))
-
-(defun org-find-top-headline (&optional pos)
- "Find the topmost parent headline and return it.
-POS when non-nil is the marker or buffer position to start the
-search from."
- (save-excursion
- (with-current-buffer (if (markerp pos) (marker-buffer pos) (current-buffer))
- (when pos (goto-char pos))
- ;; Skip up to the topmost parent.
- (while (org-up-heading-safe))
- (ignore-errors
- (replace-regexp-in-string
- "^\\[[0-9]+/[0-9]+\\] *\\|^\\[%[0-9]+\\] *" ""
- (nth 4 (org-heading-components)))))))
-
-(defvar org-agenda-filtered-by-top-headline nil)
-(defun org-agenda-filter-by-top-headline (strip)
- "Keep only those lines that are descendants from the same top headline.
-The top headline is that of the current line. With prefix arg STRIP, hide
-all lines of the category at point."
- (interactive "P")
- (if org-agenda-filtered-by-top-headline
- (progn
- (setq org-agenda-filtered-by-top-headline nil
- org-agenda-top-headline-filter nil)
- (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-or-accumulate)
- "Filter agenda entries by a regular expressions.
-You will be prompted for the regular expression, and the agenda
-view will only show entries that are matched by that expression.
-
-With one `\\[universal-argument]' prefix argument, hide entries matching the regexp.
-When there is already a regexp filter active, this command removed the
-filter. However, with two `\\[universal-argument]' prefix arguments, add a new condition to
-an already existing regexp filter."
- (interactive "P")
- (let* ((strip (equal strip-or-accumulate '(4)))
- (accumulate (equal strip-or-accumulate '(16))))
- (cond
- ((and org-agenda-regexp-filter (not accumulate))
- (org-agenda-filter-show-all-re)
- (message "Regexp filter removed"))
- (t (let ((flt (concat (if strip "-" "+")
- (read-from-minibuffer
- (if strip
- "Hide entries matching regexp: "
- "Narrow to entries matching regexp: ")))))
- (push flt org-agenda-regexp-filter)
- (org-agenda-filter-apply org-agenda-regexp-filter 'regexp))))))
-
-(defvar org-agenda-effort-filter nil)
-(defun org-agenda-filter-by-effort (strip-or-accumulate)
- "Filter agenda entries by effort.
-With no `\\[universal-argument]' prefix argument, keep entries matching the effort condition.
-With one `\\[universal-argument]' prefix argument, filter out entries matching the condition.
-With two `\\[universal-argument]' prefix arguments, add a second condition to the existing filter.
-This last option is in practice not very useful, but it is available for
-consistency with the other filter commands."
- (interactive "P")
- (let* ((efforts (split-string
- (or (cdr (assoc-string (concat org-effort-property "_ALL")
- org-global-properties
- t))
- "0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00")))
- ;; XXX: the following handles only up to 10 different
- ;; effort values.
- (allowed-keys (if (null efforts) nil
- (mapcar (lambda (n) (mod n 10)) ;turn 10 into 0
- (number-sequence 1 (length efforts)))))
- (keep (equal strip-or-accumulate '(16)))
- (negative (equal strip-or-accumulate '(4)))
- (current org-agenda-effort-filter)
- (op nil))
- (while (not (memq op '(?< ?> ?= ?_)))
- (setq op (read-char-exclusive
- "Effort operator? (> = or <) or press `_' again to remove filter")))
- ;; Select appropriate duration. Ignore non-digit characters.
- (if (eq op ?_)
- (progn
- (org-agenda-filter-show-all-effort)
- (message "Effort filter removed"))
- (let ((prompt
- (apply #'format
- (concat "Effort %c "
- (mapconcat (lambda (s) (concat "[%d]" s))
- efforts
- " "))
- op allowed-keys))
- (eff -1))
- (while (not (memq eff allowed-keys))
- (message prompt)
- (setq eff (- (read-char-exclusive) 48)))
- (org-agenda-filter-show-all-effort)
- (setq org-agenda-effort-filter
- (append
- (list (concat (if negative "-" "+")
- (char-to-string op)
- ;; Numbering is 1 2 3 ... 9 0, but we want
- ;; 0 1 2 ... 8 9.
- (nth (mod (1- eff) 10) efforts)))
- (if keep current nil)))
- (org-agenda-filter-apply org-agenda-effort-filter 'effort)))))
-
-(defun org-agenda-filter (&optional strip-or-accumulate)
- "Prompt for a general filter string and apply it to the agenda.
-
-The string may contain filter elements like
-
-+category
-+tag
-+<effort > and = are also allowed as effort operators
-+/regexp/
-
-Instead of `+', `-' is allowed to strip the agenda of matching entries.
-`+' is optional if it is not required to separate two string parts.
-Multiple filter elements can be concatenated without spaces, for example
-
- +work-John<0:10-/plot/
-
-selects entries with category `work' and effort estimates below 10 minutes,
-and deselects entries with tag `John' or matching the regexp `plot'.
-
-During entry of the filter, completion for tags, categories and effort
-values is offered. Since the syntax for categories and tags is identical
-there should be no overlap between categories and tags. If there is, tags
-get priority.
-
-A single `\\[universal-argument]' prefix arg STRIP-OR-ACCUMULATE will negate the
-entire filter, which can be useful in connection with the prompt history.
-
-A double `\\[universal-argument] \\[universal-argument]' prefix arg will add the new filter elements to the
-existing ones. A shortcut for this is to add an additional `+' at the
-beginning of the string, like `+-John'.
-
-With a triple prefix argument, execute the computed filtering defined in
-the variable `org-agenda-auto-exclude-function'."
- (interactive "P")
- (if (equal strip-or-accumulate '(64))
- ;; Execute the auto-exclude action
- (if (not org-agenda-auto-exclude-function)
- (user-error "`org-agenda-auto-exclude-function' is undefined")
- (org-agenda-filter-show-all-tag)
- (setq org-agenda-tag-filter nil)
- (dolist (tag (org-agenda-get-represented-tags))
- (let ((modifier (funcall org-agenda-auto-exclude-function tag)))
- (when modifier
- (push modifier org-agenda-tag-filter))))
- (unless (null org-agenda-tag-filter)
- (org-agenda-filter-apply org-agenda-tag-filter 'tag 'expand)))
- ;; Prompt for a filter and act
- (let* ((tag-list (org-agenda-get-represented-tags))
- (category-list (org-agenda-get-represented-categories))
- (negate (equal strip-or-accumulate '(4)))
- (cf (mapconcat #'identity org-agenda-category-filter ""))
- (tf (mapconcat #'identity org-agenda-tag-filter ""))
- ;; (rpl-fn (lambda (c) (replace-regexp-in-string "^\\+" "" (or (car c) ""))))
- (ef (replace-regexp-in-string "^\\+" "" (or (car org-agenda-effort-filter) "")))
- (rf (replace-regexp-in-string "^\\+" "" (or (car org-agenda-regexp-filter) "")))
- (ff (concat cf tf ef (when (not (equal rf "")) (concat "/" rf "/"))))
- (f-string (completing-read
- (concat
- (if negate "Negative filter" "Filter")
- " [+cat-tag<0:10-/regexp/]: ")
- #'org-agenda-filter-completion-function
- nil nil ff))
- (keep (or (if (string-match "^\\+[+-]" f-string)
- (progn (setq f-string (substring f-string 1)) t))
- (equal strip-or-accumulate '(16))))
- (fc (if keep org-agenda-category-filter))
- (ft (if keep org-agenda-tag-filter))
- (fe (if keep org-agenda-effort-filter))
- (fr (if keep org-agenda-regexp-filter))
- pm s)
- ;; If the filter contains a double-quoted string, replace a
- ;; single hyphen by the arbitrary and temporary string "~~~"
- ;; to disambiguate such hyphens from syntactic ones.
- (setq f-string (replace-regexp-in-string
- "\"\\([^\"]*\\)-\\([^\"]*\\)\"" "\"\\1~~~\\2\"" f-string))
- (while (string-match "^[ \t]*\\([-+]\\)?\\(\\([^-+<>=/ \t]+\\)\\|\\([<>=][0-9:]+\\)\\|\\(/\\([^/]+\\)/?\\)\\)" f-string)
- (setq pm (if (match-beginning 1) (match-string 1 f-string) "+"))
- (when negate
- (setq pm (if (equal pm "+") "-" "+")))
- (cond
- ((match-beginning 3)
- ;; category or tag
- (setq s (replace-regexp-in-string ; Remove the temporary special string.
- "~~~" "-" (match-string 3 f-string)))
- (cond
- ((member s tag-list)
- (org-pushnew-to-end (concat pm s) ft))
- ((member s category-list)
- (org-pushnew-to-end (concat pm ; Remove temporary double quotes.
- (replace-regexp-in-string "\"\\(.*\\)\"" "\\1" s))
- fc))
- (t (message
- "`%s%s' filter ignored because tag/category is not represented"
- pm s))))
- ((match-beginning 4)
- ;; effort
- (org-pushnew-to-end (concat pm (match-string 4 f-string)) fe))
- ((match-beginning 5)
- ;; regexp
- (org-pushnew-to-end (concat pm (match-string 6 f-string)) fr)))
- (setq f-string (substring f-string (match-end 0))))
- (org-agenda-filter-remove-all)
- (and fc (org-agenda-filter-apply
- (setq org-agenda-category-filter fc) 'category))
- (and ft (org-agenda-filter-apply
- (setq org-agenda-tag-filter ft) 'tag 'expand))
- (and fe (org-agenda-filter-apply
- (setq org-agenda-effort-filter fe) 'effort))
- (and fr (org-agenda-filter-apply
- (setq org-agenda-regexp-filter fr) 'regexp))
- (run-hooks 'org-agenda-filter-hook))))
-
-(defun org-agenda-filter-completion-function (string _predicate &optional flag)
- "Complete a complex filter string.
-FLAG specifies the type of completion operation to perform. This
-function is passed as a collection function to `completing-read',
-which see."
- (let ((completion-ignore-case t) ;tags are case-sensitive
- (confirm (lambda (x) (stringp x)))
- (prefix "")
- (operator "")
- table)
- (when (string-match "^\\(.*\\([-+<>=]\\)\\)\\([^-+<>=]*\\)$" string)
- (setq prefix (match-string 1 string)
- operator (match-string 2 string)
- string (match-string 3 string)))
- (cond
- ((member operator '("+" "-" "" nil))
- (setq table (append (org-agenda-get-represented-categories)
- (org-agenda-get-represented-tags))))
- ((member operator '("<" ">" "="))
- (setq table (split-string
- (or (cdr (assoc-string (concat org-effort-property "_ALL")
- org-global-properties
- t))
- "0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00")
- " +")))
- (t (setq table nil)))
- (pcase flag
- (`t (all-completions string table confirm))
- (`lambda (assoc string table)) ;exact match?
- (`nil
- (pcase (try-completion string table confirm)
- ((and completion (pred stringp))
- (concat prefix completion))
- (completion completion)))
- (_ nil))))
-
-(defun org-agenda-filter-remove-all ()
- "Remove all filters from the current agenda buffer."
- (interactive)
- (when org-agenda-tag-filter
- (org-agenda-filter-show-all-tag))
- (when org-agenda-category-filter
- (org-agenda-filter-show-all-cat))
- (when org-agenda-regexp-filter
- (org-agenda-filter-show-all-re))
- (when org-agenda-top-headline-filter
- (org-agenda-filter-show-all-top-filter))
- (when org-agenda-effort-filter
- (org-agenda-filter-show-all-effort))
- (org-agenda-finalize)
- (when (called-interactively-p 'interactive)
- (message "All agenda filters removed")))
-
-(defun org-agenda-filter-by-tag (strip-or-accumulate &optional char exclude)
- "Keep only those lines in the agenda buffer that have a specific tag.
-
-The tag is selected with its fast selection letter, as configured.
-
-With a `\\[universal-argument]' prefix, apply the filter negatively, stripping all matches.
-
-With a `\\[universal-argument] \\[universal-argument]' prefix, add the new tag to the existing filter
-instead of replacing it.
-
-With a `\\[universal-argument] \\[universal-argument] \\[universal-argument]' prefix, filter the literal tag, \
-i.e. don't
-filter on all its group members.
-
-A Lisp caller can specify CHAR. EXCLUDE means that the new tag
-should be used to exclude the search - the interactive user can
-also press `-' or `+' to switch between filtering and excluding."
- (interactive "P")
- (let* ((alist org-tag-alist-for-agenda)
- (seen-chars nil)
- (tag-chars (mapconcat
- (lambda (x) (if (and (not (symbolp (car x)))
- (cdr x)
- (not (member (cdr x) seen-chars)))
- (progn
- (push (cdr x) seen-chars)
- (char-to-string (cdr x)))
- ""))
- org-tag-alist-for-agenda ""))
- (valid-char-list (append '(?\t ?\r ?\\ ?. ?\s ?q)
- (string-to-list tag-chars)))
- (exclude (or exclude (equal strip-or-accumulate '(4))))
- (accumulate (equal strip-or-accumulate '(16)))
- (expand (not (equal strip-or-accumulate '(64))))
- (inhibit-read-only t)
- (current org-agenda-tag-filter)
- a tag) ;; n
- (unless char
- (while (not (memq char valid-char-list))
- (org-unlogged-message
- "%s by tag%s: [%s ]tag-char [TAB]tag %s[\\]off [q]uit"
- (if exclude "Exclude[+]" "Filter[-]")
- (if expand "" " (no grouptag expand)")
- tag-chars
- (if org-agenda-auto-exclude-function "[RET] " ""))
- (setq char (read-char-exclusive))
- ;; Excluding or filtering down
- (cond ((eq char ?-) (setq exclude t))
- ((eq char ?+) (setq exclude nil)))))
- (when (eq char ?\t)
- (unless (local-variable-p 'org-global-tags-completion-table)
- (setq-local org-global-tags-completion-table
- (org-global-tags-completion-table)))
- (let ((completion-ignore-case t))
- (setq tag (completing-read
- "Tag: " org-global-tags-completion-table nil t))))
- (cond
- ((eq char ?\r)
- (org-agenda-filter-show-all-tag)
- (when org-agenda-auto-exclude-function
- (setq org-agenda-tag-filter nil)
- (dolist (tag (org-agenda-get-represented-tags))
- (let ((modifier (funcall org-agenda-auto-exclude-function tag)))
- (when modifier
- (push modifier org-agenda-tag-filter))))
- (unless (null org-agenda-tag-filter)
- (org-agenda-filter-apply org-agenda-tag-filter 'tag expand))))
- ((eq char ?\\)
- (org-agenda-filter-show-all-tag)
- (when (get 'org-agenda-tag-filter :preset-filter)
- (org-agenda-filter-apply org-agenda-tag-filter 'tag expand)))
- ((eq char ?.)
- (setq org-agenda-tag-filter
- (mapcar (lambda(tag) (concat "+" tag))
- (org-get-at-bol 'tags)))
- (org-agenda-filter-apply org-agenda-tag-filter 'tag expand))
- ((eq char ?q)) ;If q, abort (even if there is a q-key for a tag...)
- ((or (eq char ?\s)
- (setq a (rassoc char alist))
- (and tag (setq a (cons tag nil))))
- (org-agenda-filter-show-all-tag)
- (setq tag (car a))
- (setq org-agenda-tag-filter
- (cons (concat (if exclude "-" "+") tag)
- (if accumulate current nil)))
- (org-agenda-filter-apply org-agenda-tag-filter 'tag expand))
- (t (error "Invalid tag selection character %c" char)))))
-
-(defun org-agenda-get-represented-categories ()
- "Return a list of all categories used in this agenda buffer."
- (or org-agenda-represented-categories
- (when (derived-mode-p 'org-agenda-mode)
- (let ((pos (point-min)) categories)
- (while (and (< pos (point-max))
- (setq pos (next-single-property-change
- pos 'org-category nil (point-max))))
- (push (get-text-property pos 'org-category) categories))
- (setq org-agenda-represented-categories
- ;; Enclose category names with a hyphen in double
- ;; quotes to process them specially in `org-agenda-filter'.
- (mapcar (lambda (s) (if (string-match-p "-" s) (format "\"%s\"" s) s))
- (nreverse (org-uniquify (delq nil categories)))))))))
-
-(defvar org-tag-groups-alist-for-agenda)
-(defun org-agenda-get-represented-tags ()
- "Return a list of all tags used in this agenda buffer.
-These will be lower-case, for filtering."
- (or org-agenda-represented-tags
- (when (derived-mode-p 'org-agenda-mode)
- (let ((pos (point-min)) tags-lists tt)
- (while (and (< pos (point-max))
- (setq pos (next-single-property-change
- pos 'tags nil (point-max))))
- (setq tt (get-text-property pos 'tags))
- (if tt (push tt tags-lists)))
- (setq tags-lists
- (nreverse (org-uniquify
- (delq nil (apply #'append tags-lists)))))
- (dolist (tag tags-lists)
- (mapc
- (lambda (group)
- (when (member tag group)
- (push (car group) tags-lists)))
- org-tag-groups-alist-for-agenda))
- (setq org-agenda-represented-tags tags-lists)))))
-
-(defun org-agenda-filter-make-matcher (filter type &optional expand)
- "Create the form that tests a line for agenda filter.
-Optional argument EXPAND can be used for the TYPE tag and will
-expand the tags in the FILTER if any of the tags in FILTER are
-grouptags."
- (let ((multi-pos-cats
- (and (eq type 'category)
- (string-match-p "\\+.*\\+"
- (mapconcat (lambda (cat) (substring cat 0 1))
- filter ""))))
- f f1)
- (cond
- ;; Tag filter
- ((eq type 'tag)
- (setq filter
- (delete-dups
- (append (get 'org-agenda-tag-filter :preset-filter)
- filter)))
- (dolist (x filter)
- (let ((op (string-to-char x)))
- (if expand (setq x (org-agenda-filter-expand-tags (list x) t))
- (setq x (list x)))
- (setq f1 (org-agenda-filter-make-matcher-tag-exp x op))
- (push f1 f))))
- ;; Category filter
- ((eq type 'category)
- (setq filter
- (delete-dups
- (append (get 'org-agenda-category-filter :preset-filter)
- filter)))
- (dolist (x filter)
- (if (equal "-" (substring x 0 1))
- (setq f1 (list 'not (list 'equal (substring x 1) 'cat)))
- (setq f1 (list 'equal (substring x 1) 'cat)))
- (push f1 f)))
- ;; Regexp filter
- ((eq type 'regexp)
- (setq filter
- (delete-dups
- (append (get 'org-agenda-regexp-filter :preset-filter)
- filter)))
- (dolist (x filter)
- (if (equal "-" (substring x 0 1))
- (setq f1 (list 'not (list 'string-match (substring x 1) 'txt)))
- (setq f1 (list 'string-match (substring x 1) 'txt)))
- (push f1 f)))
- ;; Effort filter
- ((eq type 'effort)
- (setq filter
- (delete-dups
- (append (get 'org-agenda-effort-filter :preset-filter)
- filter)))
- (dolist (x filter)
- (push (org-agenda-filter-effort-form x) f))))
- (cons (if multi-pos-cats 'or 'and) (nreverse f))))
-
-(defun org-agenda-filter-make-matcher-tag-exp (tags op)
- "Return a form associated to tag-expression TAGS.
-Build a form testing a line for agenda filter for
-tag-expressions. OP is an operator of type CHAR that allows the
-function to set the right switches in the returned form."
- (let (form)
- ;; Any of the expressions can match if OP is +, all must match if
- ;; the operator is -.
- (dolist (x tags (cons (if (eq op ?-) 'and 'or) form))
- (let* ((tag (substring x 1))
- (f (cond
- ((string= "" tag) 'tags)
- ((and (string-match-p "\\`{" tag) (string-match-p "}\\'" tag))
- ;; TAG is a regexp.
- (list 'org-match-any-p (substring tag 1 -1) 'tags))
- (t (list 'member tag 'tags)))))
- (push (if (eq op ?-) (list 'not f) f) form)))))
-
-(defun org-agenda-filter-effort-form (e)
- "Return the form to compare the effort of the current line with what E says.
-E looks like \"+<2:25\"."
- (let (op)
- (setq e (substring e 1))
- (setq op (string-to-char e) e (substring e 1))
- (setq op (cond ((equal op ?<) '<=)
- ((equal op ?>) '>=)
- ((equal op ??) op)
- (t '=)))
- (list 'org-agenda-compare-effort (list 'quote op)
- (org-duration-to-minutes e))))
-
-(defun org-agenda-compare-effort (op value)
- "Compare the effort of the current line with VALUE, using OP.
-If the line does not have an effort defined, return nil."
- ;; `effort-minutes' property cannot be extracted directly from
- ;; current line but is stored as a property in `txt'.
- (let ((effort (get-text-property 0 'effort-minutes (org-get-at-bol 'txt))))
- (funcall op
- (or effort (if org-agenda-sort-noeffort-is-high 32767 -1))
- value)))
-
-(defun org-agenda-filter-expand-tags (filter &optional no-operator)
- "Expand group tags in FILTER for the agenda.
-When NO-OPERATOR is non-nil, do not add the + operator to
-returned tags."
- (if org-group-tags
- (let (case-fold-search rtn)
- (mapc
- (lambda (f)
- (let (f0 dir)
- (if (string-match "^\\([+-]\\)\\(.+\\)" f)
- (setq dir (match-string 1 f) f0 (match-string 2 f))
- (setq dir (if no-operator "" "+") f0 f))
- (setq rtn (append (mapcar (lambda(f1) (concat dir f1))
- (org-tags-expand f0 t))
- rtn))))
- filter)
- (reverse rtn))
- filter))
-
-(defun org-agenda-filter-apply (filter type &optional expand)
- "Set FILTER as the new agenda filter and apply it.
-Optional argument EXPAND can be used for the TYPE tag and will
-expand the tags in the FILTER if any of the tags in FILTER are
-grouptags."
- ;; Deactivate `org-agenda-entry-text-mode' when filtering
- (when org-agenda-entry-text-mode (org-agenda-entry-text-mode))
- (setq org-agenda-filter-form (org-agenda-filter-make-matcher
- filter type expand))
- ;; 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))
- (while (not (eobp))
- (when (or (org-get-at-bol 'org-hd-marker)
- (org-get-at-bol 'org-marker))
- (org-dlet
- ((tags (org-get-at-bol 'tags))
- (cat (org-agenda-get-category))
- (txt (or (org-get-at-bol 'txt) "")))
- (unless (eval org-agenda-filter-form t)
- (org-agenda-filter-hide-line type))))
- (beginning-of-line 2)))
- (when (get-char-property (point) 'invisible)
- (ignore-errors (org-agenda-previous-line))))
-
-(defun org-agenda-filter-top-headline-apply (hl &optional negative)
- "Filter by top headline HL."
- (org-agenda-set-mode-name)
- (save-excursion
- (goto-char (point-min))
- (while (not (eobp))
- (let* ((pos (org-get-at-bol 'org-hd-marker))
- (tophl (and pos (org-find-top-headline pos))))
- (when (and tophl (funcall (if negative 'identity 'not)
- (string= hl tophl)))
- (org-agenda-filter-hide-line 'top-headline)))
- (beginning-of-line 2)))
- (when (get-char-property (point) 'invisible)
- (org-agenda-previous-line))
- (setq org-agenda-top-headline-filter hl
- org-agenda-filtered-by-top-headline t))
-
-(defun org-agenda-filter-hide-line (type)
- "If current line is TYPE, hide it in the agenda buffer."
- (let* (buffer-invisibility-spec
- (beg (max (point-min) (1- (point-at-bol))))
- (end (point-at-eol)))
- (let ((inhibit-read-only t))
- (add-text-properties
- beg end `(invisible org-filtered org-filter-type ,type)))))
-
-(defun org-agenda-remove-filter (type)
- "Remove filter of type TYPE from the agenda buffer."
- (interactive)
- (save-excursion
- (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)
- (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
- (org-agenda-remove-filter 'tag))
-(defun org-agenda-filter-show-all-re nil
- (org-agenda-remove-filter 'regexp))
-(defun org-agenda-filter-show-all-effort nil
- (org-agenda-remove-filter 'effort))
-(defun org-agenda-filter-show-all-cat nil
- (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.
-Positive selection means the term must be matched for selection of an entry."
- (interactive)
- (org-agenda-manipulate-query ?\[))
-(defun org-agenda-manipulate-query-subtract ()
- "Manipulate the query by adding a search term with negative selection.
-Negative selection means term must not be matched for selection of an entry."
- (interactive)
- (org-agenda-manipulate-query ?\]))
-(defun org-agenda-manipulate-query-add-re ()
- "Manipulate the query by adding a search regexp with positive selection.
-Positive selection means the regexp must match for selection of an entry."
- (interactive)
- (org-agenda-manipulate-query ?\{))
-(defun org-agenda-manipulate-query-subtract-re ()
- "Manipulate the query by adding a search regexp with negative selection.
-Negative selection means regexp must not match for selection of an entry."
- (interactive)
- (org-agenda-manipulate-query ?\}))
-(defun org-agenda-manipulate-query (char)
- (cond
- ((eq org-agenda-type 'agenda)
- (let ((org-agenda-include-inactive-timestamps t))
- (org-agenda-redo))
- (message "Display now includes inactive timestamps as well"))
- ((eq org-agenda-type 'search)
- (org-add-to-string
- 'org-agenda-query-string
- (if org-agenda-last-search-view-search-was-boolean
- (cdr (assoc char '((?\[ . " +") (?\] . " -")
- (?\{ . " +{}") (?\} . " -{}"))))
- " "))
- (setq org-agenda-redo-command
- (list 'org-search-view
- (car (get-text-property (min (1- (point-max)) (point))
- 'org-last-args))
- org-agenda-query-string
- (+ (length org-agenda-query-string)
- (if (member char '(?\{ ?\})) 0 1))))
- (set-register org-agenda-query-register org-agenda-query-string)
- (let ((org-agenda-overriding-arguments
- (cdr org-agenda-redo-command)))
- (org-agenda-redo)))
- (t (error "Cannot manipulate query for %s-type agenda buffers"
- org-agenda-type))))
-
-(defun org-add-to-string (var string)
- (set var (concat (symbol-value var) string)))
-
-(defun org-agenda-goto-date (date)
- "Jump to DATE in agenda."
- (interactive
- (list
- (let ((org-read-date-prefer-future org-agenda-jump-prefer-future))
- (org-read-date))))
- (let* ((day (time-to-days (org-time-string-to-time date)))
- (org-agenda-sticky-orig org-agenda-sticky)
- (org-agenda-buffer-tmp-name (buffer-name))
- (args (get-text-property (min (1- (point-max)) (point)) 'org-last-args))
- (0-arg (or current-prefix-arg (car args)))
- (2-arg (nth 2 args))
- (with-hour-p (nth 4 org-agenda-redo-command))
- (newcmd (list 'org-agenda-list 0-arg date
- (org-agenda-span-to-ndays
- 2-arg (org-time-string-to-absolute date))
- with-hour-p))
- (newargs (cdr newcmd))
- (inhibit-read-only t)
- org-agenda-sticky)
- (if (not (org-agenda-check-type t 'agenda))
- (error "Not available in non-agenda views")
- (add-text-properties (point-min) (point-max)
- `(org-redo-cmd ,newcmd org-last-args ,newargs))
- (org-agenda-redo)
- (goto-char (point-min))
- (while (not (or (= (or (get-text-property (point) 'day) 0) day)
- (save-excursion (move-beginning-of-line 2) (eobp))))
- (move-beginning-of-line 2))
- (setq org-agenda-sticky org-agenda-sticky-orig
- org-agenda-this-buffer-is-sticky org-agenda-sticky))))
-
-(defun org-agenda-goto-today ()
- "Go to today."
- (interactive)
- (org-agenda-check-type t 'agenda)
- (let* ((args (get-text-property (min (1- (point-max)) (point)) 'org-last-args))
- (curspan (nth 2 args))
- (tdpos (text-property-any (point-min) (point-max) 'org-today t)))
- (cond
- (tdpos (goto-char tdpos))
- ((eq org-agenda-type 'agenda)
- (let* ((sd (org-agenda-compute-starting-span
- (org-today) (or curspan org-agenda-span)))
- (org-agenda-overriding-arguments args))
- (setf (nth 1 org-agenda-overriding-arguments) sd)
- (org-agenda-redo)
- (org-agenda-find-same-or-today-or-agenda)))
- (t (error "Cannot find today")))))
-
-(defun org-agenda-find-same-or-today-or-agenda (&optional cnt)
- (goto-char
- (or (and cnt (text-property-any (point-min) (point-max) 'org-day-cnt cnt))
- (text-property-any (point-min) (point-max) 'org-today t)
- (text-property-any (point-min) (point-max) 'org-agenda-type 'agenda)
- (and (get-text-property (min (1- (point-max)) (point)) 'org-series)
- (org-agenda-backward-block))
- (point-min))))
-
-(defun org-agenda-backward-block ()
- "Move backward by one agenda block."
- (interactive)
- (org-agenda-forward-block 'backward))
-
-(defun org-agenda-forward-block (&optional backward)
- "Move forward by one agenda block.
-When optional argument BACKWARD is set, go backward."
- (interactive)
- (cond ((not (derived-mode-p 'org-agenda-mode))
- (user-error
- "Cannot execute this command outside of org-agenda-mode buffers"))
- ((looking-at (if backward "\\`" "\\'"))
- (message "Already at the %s block" (if backward "first" "last")))
- (t (let ((_pos (prog1 (point)
- (ignore-errors (if backward (backward-char 1)
- (move-end-of-line 1)))))
- (f (if backward
- #'previous-single-property-change
- #'next-single-property-change))
- moved dest)
- (while (and (setq dest (funcall
- f (point) 'org-agenda-structural-header))
- (not (get-text-property
- (point) 'org-agenda-structural-header)))
- (setq moved t)
- (goto-char dest))
- (if moved (move-beginning-of-line 1)
- (goto-char (if backward (point-min) (point-max)))
- (move-beginning-of-line 1)
- (message "No %s block" (if backward "previous" "further")))))))
-
-(defun org-agenda-later (arg)
- "Go forward in time by the current span.
-With prefix ARG, go forward that many times the current span."
- (interactive "p")
- (org-agenda-check-type t 'agenda)
- (let* ((wstart (window-start))
- (args (get-text-property (min (1- (point-max)) (point)) 'org-last-args))
- (span (or (nth 2 args) org-agenda-current-span))
- (sd (or (nth 1 args) (org-get-at-bol 'day) org-starting-day))
- (greg (calendar-gregorian-from-absolute sd))
- (cnt (org-get-at-bol 'org-day-cnt))
- greg2)
- (cond
- ((numberp span)
- (setq sd (+ (* span arg) sd)))
- ((eq span 'day)
- (setq sd (+ arg sd)))
- ((eq span 'week)
- (setq sd (+ (* 7 arg) sd)))
- ((eq span 'fortnight)
- (setq sd (+ (* 14 arg) sd)))
- ((eq span 'month)
- (setq greg2 (list (+ (car greg) arg) (nth 1 greg) (nth 2 greg))
- sd (calendar-absolute-from-gregorian greg2))
- (setcar greg2 (1+ (car greg2))))
- ((eq span 'year)
- (setq greg2 (list (car greg) (nth 1 greg) (+ arg (nth 2 greg)))
- sd (calendar-absolute-from-gregorian greg2))
- (setcar (nthcdr 2 greg2) (1+ (nth 2 greg2))))
- (t
- (setq sd (+ (* span arg) sd))))
- (let ((org-agenda-overriding-cmd
- ;; `cmd' may have been set by `org-agenda-run-series' which
- ;; uses `org-agenda-overriding-cmd' to decide whether
- ;; overriding is allowed for `cmd'
- (get-text-property (min (1- (point-max)) (point)) 'org-series-cmd))
- (org-agenda-overriding-arguments
- (list (car args) sd span)))
- (org-agenda-redo)
- (org-agenda-find-same-or-today-or-agenda cnt))
- (set-window-start nil wstart)))
-
-(defun org-agenda-earlier (arg)
- "Go backward in time by the current span.
-With prefix ARG, go backward that many times the current span."
- (interactive "p")
- (org-agenda-later (- arg)))
-
-(defun org-agenda-view-mode-dispatch ()
- "Call one of the view mode commands."
- (interactive)
- (org-unlogged-message
- "View: [d]ay [w]eek for[t]night [m]onth [y]ear [SPC]reset [q]uit/abort
- time[G]rid [[]inactive [f]ollow [l]og [L]og-all [c]lockcheck
- [a]rch-trees [A]rch-files clock[R]eport include[D]iary [E]ntryText")
- (pcase (read-char-exclusive)
- (?\ (call-interactively 'org-agenda-reset-view))
- (?d (call-interactively 'org-agenda-day-view))
- (?w (call-interactively 'org-agenda-week-view))
- (?t (call-interactively 'org-agenda-fortnight-view))
- (?m (call-interactively 'org-agenda-month-view))
- (?y (call-interactively 'org-agenda-year-view))
- (?l (call-interactively 'org-agenda-log-mode))
- (?L (org-agenda-log-mode '(4)))
- (?c (org-agenda-log-mode 'clockcheck))
- ((or ?F ?f) (call-interactively 'org-agenda-follow-mode))
- (?a (call-interactively 'org-agenda-archives-mode))
- (?A (org-agenda-archives-mode 'files))
- ((or ?R ?r) (call-interactively 'org-agenda-clockreport-mode))
- ((or ?E ?e) (call-interactively 'org-agenda-entry-text-mode))
- (?G (call-interactively 'org-agenda-toggle-time-grid))
- (?D (call-interactively 'org-agenda-toggle-diary))
- (?\! (call-interactively 'org-agenda-toggle-deadlines))
- (?\[ (let ((org-agenda-include-inactive-timestamps t))
- (org-agenda-check-type t 'agenda)
- (org-agenda-redo))
- (message "Display now includes inactive timestamps as well"))
- (?q (message "Abort"))
- (key (user-error "Invalid key: %s" key))))
-
-(defun org-agenda-reset-view ()
- "Switch to default view for agenda."
- (interactive)
- (org-agenda-change-time-span org-agenda-span))
-
-(defun org-agenda-day-view (&optional day-of-month)
- "Switch to daily view for agenda.
-With argument DAY-OF-MONTH, switch to that day of the month."
- (interactive "P")
- (org-agenda-change-time-span 'day day-of-month))
-
-(defun org-agenda-week-view (&optional iso-week)
- "Switch to weekly view for agenda.
-With argument ISO-WEEK, switch to the corresponding ISO week.
-If ISO-WEEK has more then 2 digits, only the last two encode
-the week. Any digits before this encode a year. So 200712
-means week 12 of year 2007. Years ranging from 70 years ago
-to 30 years in the future can also be written as 2-digit years."
- (interactive "P")
- (org-agenda-change-time-span 'week iso-week))
-
-(defun org-agenda-fortnight-view (&optional iso-week)
- "Switch to fortnightly view for agenda.
-With argument ISO-WEEK, switch to the corresponding ISO week.
-If ISO-WEEK has more then 2 digits, only the last two encode
-the week. Any digits before this encode a year. So 200712
-means week 12 of year 2007. Years ranging from 70 years ago
-to 30 years in the future can also be written as 2-digit years."
- (interactive "P")
- (org-agenda-change-time-span 'fortnight iso-week))
-
-(defun org-agenda-month-view (&optional month)
- "Switch to monthly view for agenda.
-With argument MONTH, switch to that month. If MONTH has more
-then 2 digits, only the last two encode the month. Any digits
-before this encode a year. So 200712 means December year 2007.
-Years ranging from 70 years ago to 30 years in the future can
-also be written as 2-digit years."
- (interactive "P")
- (org-agenda-change-time-span 'month month))
-
-(defun org-agenda-year-view (&optional year)
- "Switch to yearly view for agenda.
-With argument YEAR, switch to that year. Years ranging from 70
-years ago to 30 years in the future can also be written as
-2-digit years."
- (interactive "P")
- (when year
- (setq year (org-small-year-to-year year)))
- (if (y-or-n-p "Are you sure you want to compute the agenda for an entire year? ")
- (org-agenda-change-time-span 'year year)
- (error "Abort")))
-
-(defun org-agenda-change-time-span (span &optional n)
- "Change the agenda view to SPAN.
-SPAN may be `day', `week', `fortnight', `month', `year'."
- (org-agenda-check-type t 'agenda)
- (let* ((args (get-text-property (min (1- (point-max)) (point)) 'org-last-args))
- (curspan (nth 2 args)))
- (when (and (not n) (equal curspan span))
- (error "Viewing span is already \"%s\"" span))
- (let* ((sd (or (org-get-at-bol 'day)
- (nth 1 args)
- org-starting-day))
- (sd (org-agenda-compute-starting-span sd span n))
- (org-agenda-overriding-cmd
- (get-text-property (min (1- (point-max)) (point)) 'org-series-cmd))
- (org-agenda-overriding-arguments
- (list (car args) sd span)))
- (org-agenda-redo)
- (org-agenda-find-same-or-today-or-agenda))
- (org-agenda-set-mode-name)
- (message "Switched to %s view" span)))
-
-(defun org-agenda-compute-starting-span (sd span &optional n)
- "Compute starting date for agenda.
-SPAN may be `day', `week', `fortnight', `month', `year'. The return value
-is a cons cell with the starting date and the number of days,
-so that the date SD will be in that range."
- (let* ((greg (calendar-gregorian-from-absolute sd))
- ;; (dg (nth 1 greg))
- (mg (car greg))
- (yg (nth 2 greg)))
- (cond
- ((eq span 'day)
- (when n
- (setq sd (+ (calendar-absolute-from-gregorian
- (list mg 1 yg))
- n -1))))
- ((or (eq span 'week) (eq span 'fortnight))
- (let* ((nt (calendar-day-of-week
- (calendar-gregorian-from-absolute sd)))
- (d (if org-agenda-start-on-weekday
- (- nt org-agenda-start-on-weekday)
- 0))
- y1)
- (setq sd (- sd (+ (if (< d 0) 7 0) d)))
- (when n
- (require 'cal-iso)
- (when (> n 99)
- (setq y1 (org-small-year-to-year (/ n 100))
- n (mod n 100)))
- (setq sd
- (calendar-iso-to-absolute
- (list n 1
- (or y1 (nth 2 (calendar-iso-from-absolute sd)))))))))
- ((eq span 'month)
- (let (y1)
- (when (and n (> n 99))
- (setq y1 (org-small-year-to-year (/ n 100))
- n (mod n 100)))
- (setq sd (calendar-absolute-from-gregorian
- (list (or n mg) 1 (or y1 yg))))))
- ((eq span 'year)
- (setq sd (calendar-absolute-from-gregorian
- (list 1 1 (or n yg))))))
- sd))
-
-(defun org-agenda-next-date-line (&optional arg)
- "Jump to the next line indicating a date in agenda buffer."
- (interactive "p")
- (org-agenda-check-type t 'agenda)
- (beginning-of-line 1)
- ;; This does not work if user makes date format that starts with a blank
- (when (looking-at-p "^\\S-") (forward-char 1))
- (unless (re-search-forward "^\\S-" nil t arg)
- (backward-char 1)
- (error "No next date after this line in this buffer"))
- (goto-char (match-beginning 0)))
-
-(defun org-agenda-previous-date-line (&optional arg)
- "Jump to the previous line indicating a date in agenda buffer."
- (interactive "p")
- (org-agenda-check-type t 'agenda)
- (beginning-of-line 1)
- (unless (re-search-backward "^\\S-" nil t arg)
- (error "No previous date before this line in this buffer")))
-
-;; Initialize the highlight
-(defvar org-hl (make-overlay 1 1))
-(overlay-put org-hl 'face 'highlight)
-
-(defun org-highlight (begin end &optional buffer)
- "Highlight a region with overlay."
- (move-overlay org-hl begin end (or buffer (current-buffer))))
-
-(defun org-unhighlight ()
- "Detach overlay INDEX."
- (delete-overlay org-hl))
-
-(defun org-unhighlight-once ()
- "Remove the highlight from its position, and this function from the hook."
- (remove-hook 'pre-command-hook #'org-unhighlight-once)
- (org-unhighlight))
-
-(defvar org-agenda-pre-follow-window-conf nil)
-(defun org-agenda-follow-mode ()
- "Toggle follow mode in an agenda buffer."
- (interactive)
- (unless org-agenda-follow-mode
- (setq org-agenda-pre-follow-window-conf
- (current-window-configuration)))
- (setq org-agenda-follow-mode (not org-agenda-follow-mode))
- (unless org-agenda-follow-mode
- (set-window-configuration org-agenda-pre-follow-window-conf))
- (org-agenda-set-mode-name)
- (org-agenda-do-context-action)
- (message "Follow mode is %s"
- (if org-agenda-follow-mode "on" "off")))
-
-(defun org-agenda-entry-text-mode (&optional arg)
- "Toggle entry text mode in an agenda buffer."
- (interactive "P")
- (if (or org-agenda-tag-filter
- org-agenda-category-filter
- org-agenda-regexp-filter
- org-agenda-top-headline-filter)
- (user-error "Can't show entry text in filtered views")
- (setq org-agenda-entry-text-mode (or (integerp arg)
- (not org-agenda-entry-text-mode)))
- (org-agenda-entry-text-hide)
- (and org-agenda-entry-text-mode
- (let ((org-agenda-entry-text-maxlines
- (if (integerp arg) arg org-agenda-entry-text-maxlines)))
- (org-agenda-entry-text-show)))
- (org-agenda-set-mode-name)
- (message "Entry text mode is %s%s"
- (if org-agenda-entry-text-mode "on" "off")
- (if (not org-agenda-entry-text-mode) ""
- (format " (maximum number of lines is %d)"
- (if (integerp arg) arg org-agenda-entry-text-maxlines))))))
-
-(defun org-agenda-clockreport-mode ()
- "Toggle clocktable mode in an agenda buffer."
- (interactive)
- (org-agenda-check-type t 'agenda)
- (setq org-agenda-clockreport-mode (not org-agenda-clockreport-mode))
- (org-agenda-set-mode-name)
- (org-agenda-redo)
- (message "Clocktable mode is %s"
- (if org-agenda-clockreport-mode "on" "off")))
-
-(defun org-agenda-log-mode (&optional special)
- "Toggle log mode in an agenda buffer.
-
-With argument SPECIAL, show all possible log items, not only the ones
-configured in `org-agenda-log-mode-items'.
-
-With a `\\[universal-argument] \\[universal-argument]' prefix, show *only* \
-log items, nothing else."
- (interactive "P")
- (org-agenda-check-type t 'agenda)
- (setq org-agenda-show-log
- (cond
- ((equal special '(16)) 'only)
- ((eq special 'clockcheck)
- (if (eq org-agenda-show-log 'clockcheck)
- nil 'clockcheck))
- (special '(closed clock state))
- (t (not org-agenda-show-log))))
- (org-agenda-set-mode-name)
- (org-agenda-redo)
- (message "Log mode is %s" (if org-agenda-show-log "on" "off")))
-
-(defun org-agenda-archives-mode (&optional with-files)
- "Toggle inclusion of items in trees marked with :ARCHIVE:.
-When called with a prefix argument, include all archive files as well."
- (interactive "P")
- (setq org-agenda-archives-mode
- (cond ((and with-files (eq org-agenda-archives-mode t)) nil)
- (with-files t)
- (org-agenda-archives-mode nil)
- (t 'trees)))
- (org-agenda-set-mode-name)
- (org-agenda-redo)
- (message
- "%s"
- (cond
- ((eq org-agenda-archives-mode nil)
- "No archives are included")
- ((eq org-agenda-archives-mode 'trees)
- (format "Trees with :%s: tag are included" org-archive-tag))
- ((eq org-agenda-archives-mode t)
- (format "Trees with :%s: tag and all active archive files are included"
- org-archive-tag)))))
-
-(defun org-agenda-toggle-diary ()
- "Toggle diary inclusion in an agenda buffer."
- (interactive)
- (org-agenda-check-type t 'agenda)
- (setq org-agenda-include-diary (not org-agenda-include-diary))
- (org-agenda-redo)
- (org-agenda-set-mode-name)
- (message "Diary inclusion turned %s"
- (if org-agenda-include-diary "on" "off")))
-
-(defun org-agenda-toggle-deadlines ()
- "Toggle inclusion of entries with a deadline in an agenda buffer."
- (interactive)
- (org-agenda-check-type t 'agenda)
- (setq org-agenda-include-deadlines (not org-agenda-include-deadlines))
- (org-agenda-redo)
- (org-agenda-set-mode-name)
- (message "Deadlines inclusion turned %s"
- (if org-agenda-include-deadlines "on" "off")))
-
-(defun org-agenda-toggle-time-grid ()
- "Toggle time grid in an agenda buffer."
- (interactive)
- (org-agenda-check-type t 'agenda)
- (setq org-agenda-use-time-grid (not org-agenda-use-time-grid))
- (org-agenda-redo)
- (org-agenda-set-mode-name)
- (message "Time-grid turned %s"
- (if org-agenda-use-time-grid "on" "off")))
-
-(defun org-agenda-set-mode-name ()
- "Set the mode name to indicate all the small mode settings."
- (setq mode-name
- (list "Org-Agenda"
- (if (get 'org-agenda-files 'org-restrict) " []" "")
- " "
- '(:eval (org-agenda-span-name org-agenda-current-span))
- (if org-agenda-follow-mode " Follow" "")
- (if org-agenda-entry-text-mode " ETxt" "")
- (if org-agenda-include-diary " Diary" "")
- (if org-agenda-include-deadlines " Ddl" "")
- (if org-agenda-use-time-grid " Grid" "")
- (if (and (boundp 'org-habit-show-habits)
- org-habit-show-habits)
- " Habit" "")
- (cond
- ((consp org-agenda-show-log) " LogAll")
- ((eq org-agenda-show-log 'clockcheck) " ClkCk")
- (org-agenda-show-log " Log")
- (t ""))
- (if (org-agenda-filter-any) " " "")
- (if (or org-agenda-category-filter
- (get 'org-agenda-category-filter :preset-filter))
- '(:eval (propertize
- (concat "["
- (mapconcat
- #'identity
- (append
- (get 'org-agenda-category-filter :preset-filter)
- org-agenda-category-filter)
- "")
- "]")
- 'face 'org-agenda-filter-category
- 'help-echo "Category used in filtering"))
- "")
- (if (or org-agenda-tag-filter
- (get 'org-agenda-tag-filter :preset-filter))
- '(:eval (propertize
- (concat (mapconcat
- #'identity
- (append
- (get 'org-agenda-tag-filter :preset-filter)
- org-agenda-tag-filter)
- ""))
- 'face 'org-agenda-filter-tags
- 'help-echo "Tags used in filtering"))
- "")
- (if (or org-agenda-effort-filter
- (get 'org-agenda-effort-filter :preset-filter))
- '(:eval (propertize
- (concat (mapconcat
- #'identity
- (append
- (get 'org-agenda-effort-filter :preset-filter)
- org-agenda-effort-filter)
- ""))
- 'face 'org-agenda-filter-effort
- 'help-echo "Effort conditions used in filtering"))
- "")
- (if (or org-agenda-regexp-filter
- (get 'org-agenda-regexp-filter :preset-filter))
- '(:eval (propertize
- (concat (mapconcat
- (lambda (x) (concat (substring x 0 1) "/" (substring x 1) "/"))
- (append
- (get 'org-agenda-regexp-filter :preset-filter)
- org-agenda-regexp-filter)
- ""))
- 'face 'org-agenda-filter-regexp
- 'help-echo "Regexp used in filtering"))
- "")
- (if org-agenda-archives-mode
- (if (eq org-agenda-archives-mode t)
- " Archives"
- (format " :%s:" org-archive-tag))
- "")
- (if org-agenda-clockreport-mode " Clock" "")))
- (force-mode-line-update))
-
-(defun org-agenda-update-agenda-type ()
- "Update the agenda type after each command."
- (setq org-agenda-type
- (or (get-text-property (point) 'org-agenda-type)
- (get-text-property (max (point-min) (1- (point))) 'org-agenda-type))))
-
-(defun org-agenda-next-line ()
- "Move cursor to the next line, and show if follow mode is active."
- (interactive)
- (call-interactively 'next-line)
- (org-agenda-do-context-action))
-
-(defun org-agenda-previous-line ()
- "Move cursor to the previous line, and show if follow-mode is active."
- (interactive)
- (call-interactively 'previous-line)
- (org-agenda-do-context-action))
-
-(defun org-agenda-next-item (n)
- "Move cursor to next agenda item."
- (interactive "p")
- (let ((col (current-column)))
- (dotimes (_ n)
- (when (next-single-property-change (point-at-eol) 'org-marker)
- (move-end-of-line 1)
- (goto-char (next-single-property-change (point) 'org-marker))))
- (org-move-to-column col))
- (org-agenda-do-context-action))
-
-(defun org-agenda-previous-item (n)
- "Move cursor to next agenda item."
- (interactive "p")
- (dotimes (_ n)
- (let ((col (current-column))
- (goto (save-excursion
- (move-end-of-line 0)
- (previous-single-property-change (point) 'org-marker))))
- (when goto (goto-char goto))
- (org-move-to-column col)))
- (org-agenda-do-context-action))
-
-(defun org-agenda-do-context-action ()
- "Show outline path and, maybe, follow mode window."
- (let ((m (org-get-at-bol 'org-marker)))
- (when (and (markerp m) (marker-buffer m))
- (and org-agenda-follow-mode
- (if org-agenda-follow-indirect
- (org-agenda-tree-to-indirect-buffer nil)
- (org-agenda-show)))
- (and org-agenda-show-outline-path
- (org-with-point-at m (org-display-outline-path t))))))
-
-(defun org-agenda-show-tags ()
- "Show the tags applicable to the current item."
- (interactive)
- (let* ((tags (org-get-at-bol 'tags)))
- (if tags
- (message "Tags are :%s:"
- (org-no-properties (mapconcat #'identity tags ":")))
- (message "No tags associated with this line"))))
-
-(defun org-agenda-goto (&optional highlight)
- "Go to the entry at point in the corresponding Org file."
- (interactive)
- (let* ((marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- (buffer (marker-buffer marker))
- (pos (marker-position marker)))
- ;; FIXME: use `org-switch-to-buffer-other-window'?
- (switch-to-buffer-other-window buffer)
- (widen)
- (push-mark)
- (goto-char pos)
- (when (derived-mode-p 'org-mode)
- (org-show-context 'agenda)
- (recenter (/ (window-height) 2))
- (org-back-to-heading t)
- (let ((case-fold-search nil))
- (when (re-search-forward org-complex-heading-regexp nil t)
- (goto-char (match-beginning 4)))))
- (run-hooks 'org-agenda-after-show-hook)
- (and highlight (org-highlight (point-at-bol) (point-at-eol)))))
-
-(defvar org-agenda-after-show-hook nil
- "Normal hook run after an item has been shown from the agenda.
-Point is in the buffer where the item originated.")
-
-;; Defined later in org-agenda.el
-(defvar org-agenda-loop-over-headlines-in-active-region nil)
-
-(defun org-agenda-do-in-region (beg end cmd &optional arg force-arg delete)
- "Between region BEG and END, call agenda command CMD.
-When optional argument ARG is non-nil or FORCE-ARG is t, pass
-ARG to CMD. When optional argument DELETE is non-nil, assume CMD
-deletes the agenda entry and don't move to the next entry."
- (save-excursion
- (goto-char beg)
- (let ((mend (move-marker (make-marker) end))
- (all (eq org-agenda-loop-over-headlines-in-active-region t))
- (match (and (stringp org-agenda-loop-over-headlines-in-active-region)
- org-agenda-loop-over-headlines-in-active-region))
- (level (and (eq org-agenda-loop-over-headlines-in-active-region 'start-level)
- (org-get-at-bol 'level))))
- (while (< (point) mend)
- (let ((ov (make-overlay (point) (point-at-eol))))
- (if (not (or all
- (and match (looking-at-p match))
- (eq level (org-get-at-bol 'level))))
- (org-agenda-next-item 1)
- (overlay-put ov 'face 'region)
- (if (or arg force-arg) (funcall cmd arg) (funcall cmd))
- (when (not delete) (org-agenda-next-item 1))
- (delete-overlay ov)))))))
-
-;; org-agenda-[schedule,deadline,date-prompt,todo,[toggle]archive*,
-;; kill,set-property,set-effort] commands may loop over agenda
-;; entries. Commands `org-agenda-set-tags' and `org-agenda-bulk-mark'
-;; use their own mechanisms on active regions.
-(defmacro org-agenda-maybe-loop (cmd arg force-arg delete &rest body)
- "Maybe loop over agenda entries and perform CMD.
-Pass ARG, FORCE-ARG, DELETE and BODY to `org-agenda-do-in-region'."
- (declare (debug t))
- `(if (and (called-interactively-p 'any)
- org-agenda-loop-over-headlines-in-active-region
- (org-region-active-p))
- (org-agenda-do-in-region
- (region-beginning) (region-end) ,cmd ,arg ,force-arg ,delete)
- ,@body))
-
-(defun org-agenda-kill ()
- "Kill the entry or subtree belonging to the current agenda entry."
- (interactive)
- (or (eq major-mode 'org-agenda-mode) (user-error "Not in agenda"))
- (org-agenda-maybe-loop
- #'org-agenda-kill nil nil t
- (let* ((bufname-orig (buffer-name))
- (marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- (buffer (marker-buffer marker))
- (pos (marker-position marker))
- (type (org-get-at-bol 'type))
- dbeg dend (n 0))
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (save-excursion
- (goto-char pos)
- (if (and (derived-mode-p '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)
- dend (min (point-max) (1+ (point-at-eol)))))
- (goto-char dbeg)
- (while (re-search-forward "^[ \t]*\\S-" dend t) (setq n (1+ n)))))
- (when (or (eq t org-agenda-confirm-kill)
- (and (numberp org-agenda-confirm-kill)
- (> n org-agenda-confirm-kill)))
- (let ((win-conf (current-window-configuration)))
- (unwind-protect
- (and
- (prog2
- (org-agenda-tree-to-indirect-buffer nil)
- (not (y-or-n-p
- (format "Delete entry with %d lines in buffer \"%s\"? "
- n (buffer-name buffer))))
- (kill-buffer org-last-indirect-buffer))
- (error "Abort"))
- (set-window-configuration win-conf))))
- (let ((org-agenda-buffer-name bufname-orig))
- (org-remove-subtree-entries-from-agenda buffer dbeg dend))
- (with-current-buffer buffer (delete-region dbeg dend))
- (message "Agenda item and source killed")))))
-
-(defvar org-archive-default-command) ; defined in org-archive.el
-(defun org-agenda-archive-default ()
- "Archive the entry or subtree belonging to the current agenda entry."
- (interactive)
- (require 'org-archive)
- (funcall-interactively
- #'org-agenda-archive-with org-archive-default-command))
-
-(defun org-agenda-archive-default-with-confirmation ()
- "Archive the entry or subtree belonging to the current agenda entry."
- (interactive)
- (require 'org-archive)
- (funcall-interactively
- #'org-agenda-archive-with org-archive-default-command 'confirm))
-
-(defun org-agenda-archive ()
- "Archive the entry or subtree belonging to the current agenda entry."
- (interactive)
- (funcall-interactively
- #'org-agenda-archive-with 'org-archive-subtree))
-
-(defun org-agenda-archive-to-archive-sibling ()
- "Move the entry to the archive sibling."
- (interactive)
- (funcall-interactively
- #'org-agenda-archive-with 'org-archive-to-archive-sibling))
-
-(defvar org-archive-from-agenda)
-
-(defun org-agenda-archive-with (cmd &optional confirm)
- "Move the entry to the archive sibling."
- (interactive)
- (or (eq major-mode 'org-agenda-mode) (user-error "Not in agenda"))
- (org-agenda-maybe-loop
- #'org-agenda-archive-with cmd nil t
- (let* ((bufname-orig (buffer-name))
- (marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- (buffer (marker-buffer marker))
- (pos (marker-position marker)))
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (if (derived-mode-p 'org-mode)
- (if (and confirm
- (not (y-or-n-p "Archive this subtree or entry? ")))
- (error "Abort")
- (save-window-excursion
- (goto-char pos)
- (let ((org-agenda-buffer-name bufname-orig))
- (org-remove-subtree-entries-from-agenda))
- (org-back-to-heading t)
- (let ((org-archive-from-agenda t))
- (funcall cmd))))
- (error "Archiving works only in Org files")))))))
-
-(defun org-remove-subtree-entries-from-agenda (&optional buf beg end)
- "Remove all lines in the agenda that correspond to a given subtree.
-The subtree is the one in buffer BUF, starting at BEG and ending at END.
-If this information is not given, the function uses the tree at point."
- (let ((buf (or buf (current-buffer))) m p)
- (save-excursion
- (unless (and beg end)
- (org-back-to-heading t)
- (setq beg (point))
- (org-end-of-subtree t)
- (setq end (point)))
- (set-buffer (get-buffer org-agenda-buffer-name))
- (save-excursion
- (goto-char (point-max))
- (beginning-of-line 1)
- (while (not (bobp))
- (when (and (setq m (org-get-at-bol 'org-marker))
- (equal buf (marker-buffer m))
- (setq p (marker-position m))
- (>= p beg)
- (< p end))
- (let ((inhibit-read-only t))
- (delete-region (point-at-bol) (1+ (point-at-eol)))))
- (beginning-of-line 0))))))
-
-(defun org-agenda-refile (&optional goto rfloc no-update)
- "Refile the item at point.
-
-When called with `\\[universal-argument] \\[universal-argument]', \
-go to the location of the last
-refiled item.
-
-When called with `\\[universal-argument] \\[universal-argument] \
-\\[universal-argument]' prefix or when GOTO is 0, clear
-the refile cache.
-
-RFLOC can be a refile location obtained in a different way.
-
-When NO-UPDATE is non-nil, don't redo the agenda buffer."
- (interactive "P")
- (cond
- ((member goto '(0 (64)))
- (org-refile-cache-clear))
- ((equal goto '(16))
- (org-refile-goto-last-stored))
- (t
- (let* ((buffer-orig (buffer-name))
- (marker (or (org-get-at-bol 'org-hd-marker)
- (org-agenda-error)))
- (buffer (marker-buffer marker))
- ;; (pos (marker-position marker))
- (rfloc (or rfloc
- (org-refile-get-location
- (if goto "Goto" "Refile to") buffer
- org-refile-allow-creating-parent-nodes))))
- (with-current-buffer buffer
- (org-with-wide-buffer
- (goto-char marker)
- (let ((org-agenda-buffer-name buffer-orig))
- (org-remove-subtree-entries-from-agenda))
- (org-refile goto buffer rfloc))))
- (unless no-update (org-agenda-redo)))))
-
-(defun org-agenda-open-link (&optional arg)
- "Open the link(s) in the current entry, if any.
-This looks for a link in the displayed line in the agenda.
-It also looks at the text of the entry itself."
- (interactive "P")
- (let* ((marker (or (org-get-at-bol 'org-hd-marker)
- (org-get-at-bol 'org-marker)))
- (buffer (and marker (marker-buffer marker)))
- (prefix (buffer-substring (point-at-bol) (point-at-eol)))
- (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))
- trg)
- (cond
- ((and buffer lk)
- (mapcar (lambda(l)
- (with-current-buffer buffer
- (setq trg (and (string-match org-link-bracket-re l)
- (match-string 1 l)))
- (if (or (not trg) (string-match org-link-any-re trg))
- ;; Don't use `org-with-wide-buffer' here as
- ;; opening the link may result in moving the point
- (save-restriction
- (widen)
- (goto-char marker)
- (when (search-forward l nil lkend)
- (goto-char (match-beginning 0))
- (org-open-at-point)))
- ;; This is an internal link, widen the buffer
- ;; FIXME: use `org-switch-to-buffer-other-window'?
- (switch-to-buffer-other-window buffer)
- (widen)
- (goto-char marker)
- (when (search-forward l nil lkend)
- (goto-char (match-beginning 0))
- (org-open-at-point)))))
- lk))
- ((or (org-in-regexp (concat "\\(" org-link-bracket-re "\\)"))
- (save-excursion
- (beginning-of-line 1)
- (looking-at (concat ".*?\\(" org-link-bracket-re "\\)"))))
- (org-link-open-from-string (match-string 1)))
- (t (message "No link to open here")))))
-
-(defun org-agenda-copy-local-variable (var)
- "Get a variable from a referenced buffer and install it here."
- (let ((m (org-get-at-bol 'org-marker)))
- (when (and m (buffer-live-p (marker-buffer m)))
- (set (make-local-variable var)
- (with-current-buffer (marker-buffer m)
- (symbol-value var))))))
-
-(defun org-agenda-switch-to (&optional delete-other-windows)
- "Go to the Org mode file which contains the item at point.
-When optional argument DELETE-OTHER-WINDOWS is non-nil, the
-displayed Org file fills the frame."
- (interactive)
- (if (and org-return-follows-link
- (not (org-get-at-bol 'org-marker))
- (org-in-regexp org-link-bracket-re))
- (org-link-open-from-string (match-string 0))
- (let* ((marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- (buffer (marker-buffer marker))
- (pos (marker-position marker)))
- (unless buffer (user-error "Trying to switch to non-existent buffer"))
- (pop-to-buffer-same-window buffer)
- (when delete-other-windows (delete-other-windows))
- (widen)
- (goto-char pos)
- (when (derived-mode-p 'org-mode)
- (org-show-context 'agenda)
- (run-hooks 'org-agenda-after-show-hook)))))
-
-(defun org-agenda-goto-mouse (ev)
- "Go to the Org file which contains the item at the mouse click."
- (interactive "e")
- (mouse-set-point ev)
- (org-agenda-goto))
-
-(defun org-agenda-show (&optional full-entry)
- "Display the Org file which contains the item at point.
-With prefix argument FULL-ENTRY, make the entire entry visible
-if it was hidden in the outline."
- (interactive "P")
- (let ((win (selected-window)))
- (org-agenda-goto t)
- (when full-entry (org-show-entry))
- (select-window win)))
-
-(defvar org-agenda-show-window nil)
-(defun org-agenda-show-and-scroll-up (&optional arg)
- "Display the Org file which contains the item at point.
-
-When called repeatedly, scroll the window that is displaying the buffer.
-
-With a `\\[universal-argument]' prefix argument, display the item, but \
-fold drawers."
- (interactive "P")
- (let ((win (selected-window)))
- (if (and (window-live-p org-agenda-show-window)
- (eq this-command last-command))
- (progn
- (select-window org-agenda-show-window)
- (ignore-errors (scroll-up)))
- (org-agenda-goto t)
- (org-show-entry)
- (if arg (org-cycle-hide-drawers 'children)
- (org-with-wide-buffer
- (narrow-to-region (org-entry-beginning-position)
- (org-entry-end-position))
- (org-show-all '(drawers))))
- (setq org-agenda-show-window (selected-window)))
- (select-window win)))
-
-(defun org-agenda-show-scroll-down ()
- "Scroll down the window showing the agenda."
- (interactive)
- (let ((win (selected-window)))
- (when (window-live-p org-agenda-show-window)
- (select-window org-agenda-show-window)
- (ignore-errors (scroll-down))
- (select-window win))))
-
-(defun org-agenda-show-1 (&optional more)
- "Display the Org file which contains the item at point.
-The prefix arg selects the amount of information to display:
-
-0 hide the subtree
-1 just show the entry according to defaults.
-2 show the children view
-3 show the subtree view
-4 show the entire subtree and any drawers
-With prefix argument FULL-ENTRY, make the entire entry visible
-if it was hidden in the outline."
- (interactive "p")
- (let ((win (selected-window)))
- (org-agenda-goto t)
- (org-back-to-heading)
- (set-window-start (selected-window) (point-at-bol))
- (cond
- ((= more 0)
- (org-flag-subtree t)
- (save-excursion
- (org-back-to-heading)
- (run-hook-with-args 'org-cycle-hook 'folded))
- (message "Remote: FOLDED"))
- ((and (called-interactively-p 'any) (= more 1))
- (message "Remote: show with default settings"))
- ((= more 2)
- (outline-show-entry)
- (org-show-children)
- (save-excursion
- (org-back-to-heading)
- (run-hook-with-args 'org-cycle-hook 'children))
- (message "Remote: CHILDREN"))
- ((= more 3)
- (outline-show-subtree)
- (save-excursion
- (org-back-to-heading)
- (run-hook-with-args 'org-cycle-hook 'subtree))
- (message "Remote: SUBTREE"))
- ((> more 3)
- (outline-show-subtree)
- (message "Remote: SUBTREE AND ALL DRAWERS")))
- (select-window win)))
-
-(defvar org-agenda-cycle-counter nil)
-(defun org-agenda-cycle-show (&optional n)
- "Show the current entry in another window, with default settings.
-
-Default settings are taken from `org-show-context-detail'. When
-use repeatedly in immediate succession, the remote entry will
-cycle through visibility
-
- children -> subtree -> folded
-
-When called with a numeric prefix arg, that arg will be passed through to
-`org-agenda-show-1'. For the interpretation of that argument, see the
-docstring of `org-agenda-show-1'."
- (interactive "P")
- (if (integerp n)
- (setq org-agenda-cycle-counter n)
- (if (not (eq last-command this-command))
- (setq org-agenda-cycle-counter 1)
- (if (equal org-agenda-cycle-counter 0)
- (setq org-agenda-cycle-counter 2)
- (setq org-agenda-cycle-counter (1+ org-agenda-cycle-counter))
- (when (> org-agenda-cycle-counter 3)
- (setq org-agenda-cycle-counter 0)))))
- (org-agenda-show-1 org-agenda-cycle-counter))
-
-(defun org-agenda-recenter (arg)
- "Display the Org file which contains the item at point and recenter."
- (interactive "P")
- (let ((win (selected-window)))
- (org-agenda-goto t)
- (recenter arg)
- (select-window win)))
-
-(defun org-agenda-show-mouse (ev)
- "Display the Org file which contains the item at the mouse click."
- (interactive "e")
- (mouse-set-point ev)
- (org-agenda-show))
-
-(defun org-agenda-check-no-diary ()
- "Check if the entry is a diary link and abort if yes."
- (when (org-get-at-bol 'org-agenda-diary-link)
- (org-agenda-error)))
-
-(defun org-agenda-error ()
- "Throw an error when a command is not allowed in the agenda."
- (user-error "Command not allowed in this line"))
-
-(defun org-agenda-tree-to-indirect-buffer (arg)
- "Show the subtree corresponding to the current entry in an indirect buffer.
-This calls the command `org-tree-to-indirect-buffer' from the original buffer.
-
-With a numerical prefix ARG, go up to this level and then take that tree.
-With a negative numeric ARG, go up by this number of levels.
-
-With a `\\[universal-argument]' prefix, make a separate frame for this tree, \
-i.e. don't use
-the dedicated frame."
- (interactive "P")
- (if current-prefix-arg
- (org-agenda-do-tree-to-indirect-buffer arg)
- (let ((agenda-buffer (buffer-name))
- (agenda-window (selected-window))
- (indirect-window
- (and org-last-indirect-buffer
- (get-buffer-window org-last-indirect-buffer))))
- (save-window-excursion (org-agenda-do-tree-to-indirect-buffer arg))
- (unless (or (eq org-indirect-buffer-display 'new-frame)
- (eq org-indirect-buffer-display 'dedicated-frame))
- (unwind-protect
- (unless (and indirect-window (window-live-p indirect-window))
- (setq indirect-window (split-window agenda-window)))
- (and indirect-window (select-window indirect-window))
- (switch-to-buffer org-last-indirect-buffer :norecord)
- (fit-window-to-buffer indirect-window)))
- (select-window (get-buffer-window agenda-buffer))
- (setq org-agenda-last-indirect-buffer org-last-indirect-buffer))))
-
-(defun org-agenda-do-tree-to-indirect-buffer (arg)
- "Same as `org-agenda-tree-to-indirect-buffer' without saving window."
- (org-agenda-check-no-diary)
- (let* ((marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- (buffer (marker-buffer marker))
- (pos (marker-position marker)))
- (with-current-buffer buffer
- (save-excursion
- (goto-char pos)
- (org-tree-to-indirect-buffer arg)))))
-
-(defvar org-last-heading-marker (make-marker)
- "Marker pointing to the headline that last changed its TODO state
-by a remote command from the agenda.")
-
-(defun org-agenda-todo-nextset ()
- "Switch TODO entry to next sequence."
- (interactive)
- (org-agenda-todo 'nextset))
-
-(defun org-agenda-todo-previousset ()
- "Switch TODO entry to previous sequence."
- (interactive)
- (org-agenda-todo 'previousset))
-
-(defvar org-agenda-headline-snapshot-before-repeat)
-
-(defun org-agenda-todo (&optional arg)
- "Cycle TODO state of line at point, also in Org file.
-This changes the line at point, all other lines in the agenda referring to
-the same tree node, and the headline of the tree node in the Org file."
- (interactive "P")
- (org-agenda-check-no-diary)
- (org-agenda-maybe-loop
- #'org-agenda-todo arg nil nil
- (let* ((col (current-column))
- (marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- (buffer (marker-buffer marker))
- (pos (marker-position marker))
- (hdmarker (org-get-at-bol 'org-hd-marker))
- (todayp (org-agenda-today-p (org-get-at-bol 'day)))
- (inhibit-read-only t)
- org-loop-over-headlines-in-active-region
- org-agenda-headline-snapshot-before-repeat newhead just-one)
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (org-show-context 'agenda)
- (let ((current-prefix-arg arg))
- (call-interactively 'org-todo)
- ;; Make sure that log is recorded in current undo.
- (when (and org-log-setup
- (not (eq org-log-note-how 'note)))
- (org-add-log-note)))
- (and (bolp) (forward-char 1))
- (setq newhead (org-get-heading))
- (when (and org-agenda-headline-snapshot-before-repeat
- (not (equal org-agenda-headline-snapshot-before-repeat
- newhead))
- todayp)
- (setq newhead org-agenda-headline-snapshot-before-repeat
- just-one t))
- (save-excursion
- (org-back-to-heading)
- (move-marker org-last-heading-marker (point))))
- (beginning-of-line 1)
- (save-window-excursion
- (org-agenda-change-all-lines newhead hdmarker 'fixface just-one))
- (when (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)
- (org-agenda-mark-clocking-task)))))
-
-(defun org-agenda-add-note (&optional _arg)
- "Add a time-stamped note to the entry at point."
- (interactive) ;; "P"
- (org-agenda-check-no-diary)
- (let* ((marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- (buffer (marker-buffer marker))
- (pos (marker-position marker))
- (_hdmarker (org-get-at-bol 'org-hd-marker))
- (inhibit-read-only t))
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (org-show-context 'agenda)
- (org-add-note))))
-
-(defun org-agenda-change-all-lines (newhead hdmarker
- &optional fixface just-this)
- "Change all lines in the agenda buffer which match HDMARKER.
-The new content of the line will be NEWHEAD (as modified by
-`org-agenda-format-item'). HDMARKER is checked with
-`equal' against all `org-hd-marker' text properties in the file.
-If FIXFACE is non-nil, the face of each item is modified according to
-the new TODO state.
-If JUST-THIS is non-nil, change just the current line, not all.
-If FORCE-TAGS is non-nil, the car of it returns the new tags."
- (let* ((inhibit-read-only t)
- (line (org-current-line))
- (org-agenda-buffer (current-buffer))
- (thetags (with-current-buffer (marker-buffer hdmarker)
- (org-get-tags hdmarker)))
- props m undone-face done-face finish new dotime level cat tags) ;; pl
- (save-excursion
- (goto-char (point-max))
- (beginning-of-line 1)
- (while (not finish)
- (setq finish (bobp))
- (when (and (setq m (org-get-at-bol 'org-hd-marker))
- (or (not just-this) (= (org-current-line) line))
- (equal m hdmarker))
- (setq props (text-properties-at (point))
- dotime (org-get-at-bol 'dotime)
- cat (org-agenda-get-category)
- level (org-get-at-bol 'level)
- tags thetags
- new
- (let ((org-prefix-format-compiled
- (or (get-text-property (min (1- (point-max)) (point)) 'format)
- org-prefix-format-compiled))
- (extra (org-get-at-bol 'extra)))
- (with-current-buffer (marker-buffer hdmarker)
- (org-with-wide-buffer
- (org-agenda-format-item extra newhead level cat tags dotime))))
- ;; 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))
- (beginning-of-line 1)
- (cond
- ((equal new "") (delete-region (point) (line-beginning-position 2)))
- ((looking-at ".*")
- ;; When replacing the whole line, preserve bulk mark
- ;; overlay, if any.
- (let ((mark (catch :overlay
- (dolist (o (overlays-in (point) (+ 2 (point))))
- (when (eq (overlay-get o 'type)
- 'org-marked-entry-overlay)
- (throw :overlay o))))))
- (replace-match new t t)
- (beginning-of-line)
- (when mark (move-overlay mark (point) (+ 2 (point)))))
- (add-text-properties (point-at-bol) (point-at-eol) props)
- (when fixface
- (add-text-properties
- (point-at-bol) (point-at-eol)
- (list 'face
- (if org-last-todo-state-is-todo
- undone-face done-face))))
- (org-agenda-highlight-todo 'line)
- (beginning-of-line 1))
- (t (error "Line update did not work")))
- (save-restriction
- (narrow-to-region (point-at-bol) (point-at-eol))
- (org-agenda-finalize)))
- (beginning-of-line 0)))))
-
-(defun org-agenda-align-tags (&optional line)
- "Align all tags in agenda items to `org-agenda-tags-column'.
-When optional argument LINE is non-nil, align tags only on the
-current line."
- (let ((inhibit-read-only t)
- (org-agenda-tags-column (if (eq 'auto org-agenda-tags-column)
- (- (window-text-width))
- org-agenda-tags-column))
- (end (and line (line-end-position)))
- l c)
- (save-excursion
- (goto-char (if line (line-beginning-position) (point-min)))
- (while (re-search-forward org-tag-group-re end t)
- (add-text-properties
- (match-beginning 1) (match-end 1)
- (list 'face (delq nil (let ((prop (get-text-property
- (match-beginning 1) 'face)))
- (or (listp prop) (setq prop (list prop)))
- (if (memq 'org-tag prop)
- prop
- (cons 'org-tag prop))))))
- (setq l (string-width (match-string 1))
- c (if (< org-agenda-tags-column 0)
- (- (abs org-agenda-tags-column) l)
- org-agenda-tags-column))
- (goto-char (match-beginning 1))
- (delete-region (save-excursion (skip-chars-backward " \t") (point))
- (point))
- (insert (org-add-props
- (make-string (max 1 (- c (current-column))) ?\s)
- (plist-put (copy-sequence (text-properties-at (point)))
- 'face nil))))
- (goto-char (point-min))
- (org-font-lock-add-tag-faces (point-max)))))
-
-(defun org-agenda-priority-up ()
- "Increase the priority of line at point, also in Org file."
- (interactive)
- (org-agenda-priority 'up))
-
-(defun org-agenda-priority-down ()
- "Decrease the priority of line at point, also in Org file."
- (interactive)
- (org-agenda-priority 'down))
-
-(defun org-agenda-priority (&optional force-direction)
- "Set the priority of line at point, also in Org file.
-This changes the line at point, all other lines in the agenda
-referring to the same tree node, and the headline of the tree
-node in the Org file.
-
-Called with one universal prefix arg, show the priority instead
-of setting it.
-
-When called programmatically, FORCE-DIRECTION can be `set', `up',
-`down', or a character."
- (interactive "P")
- (unless org-priority-enable-commands
- (user-error "Priority commands are disabled"))
- (org-agenda-check-no-diary)
- (let* ((col (current-column))
- (hdmarker (org-get-at-bol 'org-hd-marker))
- (buffer (marker-buffer hdmarker))
- (pos (marker-position hdmarker))
- (inhibit-read-only t)
- newhead)
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (org-show-context 'agenda)
- (org-priority force-direction)
- (end-of-line 1)
- (setq newhead (org-get-heading)))
- (org-agenda-change-all-lines newhead hdmarker)
- (org-move-to-column col))))
-
-;; FIXME: should fix the tags property of the agenda line.
-(defun org-agenda-set-tags (&optional tag onoff)
- "Set tags for the current headline."
- (interactive)
- (org-agenda-check-no-diary)
- (if (and (org-region-active-p) (called-interactively-p 'any))
- (call-interactively 'org-change-tag-in-region)
- (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
- (org-agenda-error)))
- (buffer (marker-buffer hdmarker))
- (pos (marker-position hdmarker))
- (inhibit-read-only t)
- newhead)
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (org-show-context 'agenda)
- (if tag
- (org-toggle-tag tag onoff)
- (call-interactively #'org-set-tags-command))
- (end-of-line 1)
- (setq newhead (org-get-heading)))
- (org-agenda-change-all-lines newhead hdmarker)
- (beginning-of-line 1)))))
-
-(defun org-agenda-set-property ()
- "Set a property for the current headline."
- (interactive)
- (org-agenda-check-no-diary)
- (org-agenda-maybe-loop
- #'org-agenda-set-property nil nil nil
- (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
- (org-agenda-error)))
- (buffer (marker-buffer hdmarker))
- (pos (marker-position hdmarker))
- (inhibit-read-only t)
- ) ;; newhead
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (org-show-context 'agenda)
- (call-interactively 'org-set-property))))))
-
-(defun org-agenda-set-effort ()
- "Set the effort property for the current headline."
- (interactive)
- (org-agenda-check-no-diary)
- (org-agenda-maybe-loop
- #'org-agenda-set-effort nil nil nil
- (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
- (org-agenda-error)))
- (buffer (marker-buffer hdmarker))
- (pos (marker-position hdmarker))
- (inhibit-read-only t)
- newhead)
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (org-show-context 'agenda)
- (call-interactively 'org-set-effort)
- (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."
- (interactive)
- (org-agenda-check-no-diary)
- (org-agenda-maybe-loop
- #'org-agenda-toggle-archive-tag nil nil nil
- (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
- (org-agenda-error)))
- (buffer (marker-buffer hdmarker))
- (pos (marker-position hdmarker))
- (inhibit-read-only t)
- newhead)
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (org-show-context 'agenda)
- (call-interactively 'org-toggle-archive-tag)
- (end-of-line 1)
- (setq newhead (org-get-heading)))
- (org-agenda-change-all-lines newhead hdmarker)
- (beginning-of-line 1)))))
-
-(defun org-agenda-do-date-later (arg)
- (interactive "P")
- (cond
- ((or (equal arg '(16))
- (memq last-command
- '(org-agenda-date-later-minutes org-agenda-date-earlier-minutes)))
- (setq this-command 'org-agenda-date-later-minutes)
- (org-agenda-date-later-minutes 1))
- ((or (equal arg '(4))
- (memq last-command
- '(org-agenda-date-later-hours org-agenda-date-earlier-hours)))
- (setq this-command 'org-agenda-date-later-hours)
- (org-agenda-date-later-hours 1))
- (t
- (org-agenda-date-later (prefix-numeric-value arg)))))
-
-(defun org-agenda-do-date-earlier (arg)
- (interactive "P")
- (cond
- ((or (equal arg '(16))
- (memq last-command
- '(org-agenda-date-later-minutes org-agenda-date-earlier-minutes)))
- (setq this-command 'org-agenda-date-earlier-minutes)
- (org-agenda-date-earlier-minutes 1))
- ((or (equal arg '(4))
- (memq last-command
- '(org-agenda-date-later-hours org-agenda-date-earlier-hours)))
- (setq this-command 'org-agenda-date-earlier-hours)
- (org-agenda-date-earlier-hours 1))
- (t
- (org-agenda-date-earlier (prefix-numeric-value arg)))))
-
-(defun org-agenda-date-later (arg &optional what)
- "Change the date of this item to ARG day(s) later."
- (interactive "p")
- (org-agenda-check-type t 'agenda)
- (org-agenda-check-no-diary)
- (let* ((marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- (buffer (marker-buffer marker))
- (pos (marker-position marker))
- cdate today)
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (unless (org-at-timestamp-p 'lax) (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))
- (when (> 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)
- "Change the date of this item to ARG day(s) earlier."
- (interactive "p")
- (org-agenda-date-later (- arg) what))
-
-(defun org-agenda-date-later-minutes (arg)
- "Change the time of this item, in units of `org-time-stamp-rounding-minutes'."
- (interactive "p")
- (setq arg (* arg (cadr org-time-stamp-rounding-minutes)))
- (org-agenda-date-later arg 'minute))
-
-(defun org-agenda-date-earlier-minutes (arg)
- "Change the time of this item, in units of `org-time-stamp-rounding-minutes'."
- (interactive "p")
- (setq arg (* arg (cadr org-time-stamp-rounding-minutes)))
- (org-agenda-date-earlier arg 'minute))
-
-(defun org-agenda-date-later-hours (arg)
- "Change the time of this item, in hour steps."
- (interactive "p")
- (org-agenda-date-later arg 'hour))
-
-(defun org-agenda-date-earlier-hours (arg)
- "Change the time of this item, in hour steps."
- (interactive "p")
- (org-agenda-date-earlier arg 'hour))
-
-(defun org-agenda-show-new-time (marker stamp &optional prefix)
- "Show new date stamp via text properties."
- ;; We use text properties to make this undoable
- (let ((inhibit-read-only t))
- (setq stamp (concat prefix " => " stamp " "))
- (save-excursion
- (goto-char (point-max))
- (while (not (bobp))
- (when (equal marker (org-get-at-bol 'org-marker))
- (remove-text-properties (line-beginning-position)
- (line-end-position)
- '(display nil))
- (org-move-to-column
- (- (if (fboundp 'window-font-width)
- (/ (window-width nil t) (window-font-width))
- ;; Fall back to pre-9.3.3 behavior on Emacs <25.
- (window-width))
- (length stamp))
- t)
- (add-text-properties
- (1- (point)) (point-at-eol)
- (list 'display (org-add-props stamp nil
- 'face '(secondary-selection default))))
- (beginning-of-line 1))
- (beginning-of-line 0)))))
-
-(defun org-agenda-date-prompt (arg)
- "Change the date of this item. Date is prompted for, with default today.
-The prefix ARG is passed to the `org-time-stamp' command and can therefore
-be used to request time specification in the time stamp."
- (interactive "P")
- (org-agenda-check-type t 'agenda)
- (org-agenda-check-no-diary)
- (org-agenda-maybe-loop
- #'org-agenda-date-prompt arg t nil
- (let* ((marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- (buffer (marker-buffer marker))
- (pos (marker-position marker)))
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (unless (org-at-timestamp-p 'lax) (error "Cannot find time stamp"))
- (org-time-stamp arg (equal (char-after (match-beginning 0)) ?\[)))
- (org-agenda-show-new-time marker org-last-changed-timestamp))
- (message "Time stamp changed to %s" org-last-changed-timestamp))))
-
-(defun org-agenda-schedule (arg &optional time)
- "Schedule the item at point.
-ARG is passed through to `org-schedule'."
- (interactive "P")
- (org-agenda-check-type t 'agenda 'todo 'tags 'search)
- (org-agenda-check-no-diary)
- (org-agenda-maybe-loop
- #'org-agenda-schedule arg t nil
- (let* ((marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- ;; (type (marker-insertion-type marker))
- (buffer (marker-buffer marker))
- (pos (marker-position marker))
- ts)
- (set-marker-insertion-type marker t)
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (setq ts (org-schedule arg time)))
- (org-agenda-show-new-time marker ts " S"))
- (message "%s" ts))))
-
-(defun org-agenda-deadline (arg &optional time)
- "Schedule the item at point.
-ARG is passed through to `org-deadline'."
- (interactive "P")
- (org-agenda-check-type t 'agenda 'todo 'tags 'search)
- (org-agenda-check-no-diary)
- (org-agenda-maybe-loop
- #'org-agenda-deadline arg t nil
- (let* ((marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- (buffer (marker-buffer marker))
- (pos (marker-position marker))
- ts)
- (org-with-remote-undo buffer
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (setq ts (org-deadline arg time)))
- (org-agenda-show-new-time marker ts " D"))
- (message "%s" ts))))
-
-(defun org-agenda-clock-in (&optional arg)
- "Start the clock on the currently selected item."
- (interactive "P")
- (org-agenda-check-no-diary)
- (if (equal arg '(4))
- (org-clock-in arg)
- (let* ((marker (or (org-get-at-bol 'org-marker)
- (org-agenda-error)))
- (hdmarker (or (org-get-at-bol 'org-hd-marker) marker))
- (pos (marker-position marker))
- (col (current-column))
- newhead)
- (org-with-remote-undo (marker-buffer marker)
- (with-current-buffer (marker-buffer marker)
- (widen)
- (goto-char pos)
- (org-show-context 'agenda)
- (org-clock-in arg)
- (setq newhead (org-get-heading)))
- (org-agenda-change-all-lines newhead hdmarker))
- (org-move-to-column col))))
-
-(defun org-agenda-clock-out ()
- "Stop the currently running clock."
- (interactive)
- (unless (marker-buffer org-clock-marker)
- (user-error "No running clock"))
- (let ((marker (make-marker)) (col (current-column)) newhead)
- (org-with-remote-undo (marker-buffer org-clock-marker)
- (with-current-buffer (marker-buffer org-clock-marker)
- (org-with-wide-buffer
- (goto-char org-clock-marker)
- (org-back-to-heading t)
- (move-marker marker (point))
- (org-clock-out)
- (setq newhead (org-get-heading)))))
- (org-agenda-change-all-lines newhead marker)
- (move-marker marker nil)
- (org-move-to-column col)
- (org-agenda-unmark-clocking-task)))
-
-(defun org-agenda-clock-cancel (&optional _arg)
- "Cancel the currently running clock."
- (interactive) ;; "P"
- (unless (marker-buffer org-clock-marker)
- (user-error "No running clock"))
- (org-with-remote-undo (marker-buffer org-clock-marker)
- (org-clock-cancel)))
-
-(defun org-agenda-clock-goto ()
- "Jump to the currently clocked in task within the agenda.
-If the currently clocked in task is not listed in the agenda
-buffer, display it in another window."
- (interactive)
- (let (pos)
- (mapc (lambda (o)
- (when (eq (overlay-get o 'type) 'org-agenda-clocking)
- (setq pos (overlay-start o))))
- (overlays-in (point-min) (point-max)))
- (cond (pos (goto-char pos))
- ;; If the currently clocked entry is not in the agenda
- ;; buffer, we visit it in another window:
- ((bound-and-true-p org-clock-current-task)
- (org-switch-to-buffer-other-window (org-clock-goto)))
- (t (message "No running clock, use `C-c C-x C-j' to jump to the most recent one")))))
-
-(defun org-agenda-diary-entry-in-org-file ()
- "Make a diary entry in the file `org-agenda-diary-file'."
- (let (d1 d2 char (text "") dp1 dp2)
- (if (equal (buffer-name) "*Calendar*")
- (setq d1 (calendar-cursor-to-date t)
- d2 (car calendar-mark-ring))
- (setq dp1 (get-text-property (point-at-bol) 'day))
- (unless dp1 (user-error "No date defined in current line"))
- (setq d1 (calendar-gregorian-from-absolute dp1)
- d2 (and (ignore-errors (mark))
- (save-excursion
- (goto-char (mark))
- (setq dp2 (get-text-property (point-at-bol) 'day)))
- (calendar-gregorian-from-absolute dp2))))
- (message "Diary entry: [d]ay [a]nniversary [b]lock [j]ump to date tree")
- (setq char (read-char-exclusive))
- (cond
- ((equal char ?d)
- (setq text (read-string "Day entry: "))
- (org-agenda-add-entry-to-org-agenda-diary-file 'day text d1)
- (and (equal (buffer-name) org-agenda-buffer-name) (org-agenda-redo)))
- ((equal char ?a)
- (setq d1 (list (car d1) (nth 1 d1)
- (read-number (format "Reference year [%d]: " (nth 2 d1))
- (nth 2 d1))))
- (setq text (read-string "Anniversary (use %d to show years): "))
- (org-agenda-add-entry-to-org-agenda-diary-file 'anniversary text d1)
- (and (equal (buffer-name) org-agenda-buffer-name) (org-agenda-redo)))
- ((equal char ?b)
- (setq text (read-string "Block entry: "))
- (unless (and d1 d2 (not (equal d1 d2)))
- (user-error "No block of days selected"))
- (org-agenda-add-entry-to-org-agenda-diary-file 'block text d1 d2)
- (and (equal (buffer-name) org-agenda-buffer-name) (org-agenda-redo)))
- ((equal char ?j)
- (org-switch-to-buffer-other-window
- (find-file-noselect org-agenda-diary-file))
- (require 'org-datetree)
- (org-datetree-find-date-create d1)
- (org-reveal t))
- (t (user-error "Invalid selection character `%c'" char)))))
-
-(defcustom org-agenda-insert-diary-strategy 'date-tree
- "Where in `org-agenda-diary-file' should new entries be added?
-Valid values:
-
-date-tree in the date tree, as first child of the date
-date-tree-last in the date tree, as last child of the date
-top-level as top-level entries at the end of the file."
- :group 'org-agenda
- :type '(choice
- (const :tag "first in a date tree" date-tree)
- (const :tag "last in a date tree" date-tree-last)
- (const :tag "as top level at end of file" top-level)))
-
-(defcustom org-agenda-insert-diary-extract-time nil
- "Non-nil means extract any time specification from the diary entry."
- :group 'org-agenda
- :version "24.1"
- :type 'boolean)
-
-(defcustom org-agenda-bulk-mark-char ">"
- "A single-character string to be used as the bulk mark."
- :group 'org-agenda
- :version "24.1"
- :type 'string)
-
-(defun org-agenda-add-entry-to-org-agenda-diary-file (type text &optional d1 d2)
- "Add a diary entry with TYPE to `org-agenda-diary-file'.
-If TEXT is not empty, it will become the headline of the new entry, and
-the resulting entry will not be shown. When TEXT is empty, switch to
-`org-agenda-diary-file' and let the user finish the entry there."
- (let ((cw (current-window-configuration)))
- (org-switch-to-buffer-other-window
- (find-file-noselect org-agenda-diary-file))
- (widen)
- (goto-char (point-min))
- (cl-case type
- (anniversary
- (or (re-search-forward "^\\*[ \t]+Anniversaries" nil t)
- (progn
- (or (org-at-heading-p t)
- (progn
- (outline-next-heading)
- (insert "* Anniversaries\n\n")
- (beginning-of-line -1)))))
- (outline-next-heading)
- (org-back-over-empty-lines)
- (backward-char 1)
- (insert "\n")
- (insert (format "%%%%(org-anniversary %d %2d %2d) %s"
- (nth 2 d1) (car d1) (nth 1 d1) text)))
- (day
- (let ((org-prefix-has-time t)
- (org-agenda-time-leading-zero t)
- fmt time time2)
- (when org-agenda-insert-diary-extract-time
- ;; Use org-agenda-format-item to parse text for a time-range and
- ;; remove it. FIXME: This is a hack, we should refactor
- ;; that function to make time extraction available separately
- (setq fmt (org-agenda-format-item nil text nil nil nil t)
- time (get-text-property 0 'time fmt)
- time2 (if (> (length time) 0)
- ;; split-string removes trailing ...... if
- ;; no end time given. First space
- ;; separates time from date.
- (concat " " (car (split-string time "\\.")))
- nil)
- text (get-text-property 0 'txt fmt)))
- (if (eq org-agenda-insert-diary-strategy 'top-level)
- (org-agenda-insert-diary-as-top-level text)
- (require 'org-datetree)
- (org-datetree-find-date-create d1)
- (org-agenda-insert-diary-make-new-entry text))
- (org-insert-time-stamp (org-time-from-absolute
- (calendar-absolute-from-gregorian d1))
- nil nil nil nil time2))
- (end-of-line 0))
- ((block) ;; Wrap this in (strictly unnecessary) parens because
- ;; otherwise the indentation gets confused by the
- ;; special meaning of 'block
- (when (> (calendar-absolute-from-gregorian d1)
- (calendar-absolute-from-gregorian d2))
- (setq d1 (prog1 d2 (setq d2 d1))))
- (if (eq org-agenda-insert-diary-strategy 'top-level)
- (org-agenda-insert-diary-as-top-level text)
- (require 'org-datetree)
- (org-datetree-find-date-create d1)
- (org-agenda-insert-diary-make-new-entry text))
- (org-insert-time-stamp (org-time-from-absolute
- (calendar-absolute-from-gregorian d1)))
- (insert "--")
- (org-insert-time-stamp (org-time-from-absolute
- (calendar-absolute-from-gregorian d2)))
- (end-of-line 0)))
- (if (string-match "\\S-" text)
- (progn
- (set-window-configuration cw)
- (message "%s entry added to %s"
- (capitalize (symbol-name type))
- (abbreviate-file-name org-agenda-diary-file)))
- (org-reveal t)
- (message "Please finish entry here"))))
-
-(defun org-agenda-insert-diary-as-top-level (text)
- "Make new entry as a top-level entry at the end of the file.
-Add TEXT as headline, and position the cursor in the second line so that
-a timestamp can be added there."
- (widen)
- (goto-char (point-max))
- (unless (bolp) (insert "\n"))
- (org-insert-heading nil t t)
- (insert text)
- (org-end-of-meta-data)
- (unless (bolp) (insert "\n"))
- (when org-adapt-indentation (indent-to-column 2)))
-
-(defun org-agenda-insert-diary-make-new-entry (text)
- "Make a new entry with TEXT as a child of the current subtree.
-Position the point in the heading's first body line so that
-a timestamp can be added there."
- (cond
- ((eq org-agenda-insert-diary-strategy 'date-tree-last)
- (end-of-line)
- (org-insert-heading '(4) t)
- (org-do-demote))
- (t
- (outline-next-heading)
- (org-back-over-empty-lines)
- (unless (looking-at "[ \t]*$") (save-excursion (insert "\n")))
- (org-insert-heading nil t)
- (org-do-demote)))
- (let ((col (current-column)))
- (insert text)
- (org-end-of-meta-data)
- ;; Ensure point is left on a blank line, at proper indentation.
- (unless (bolp) (insert "\n"))
- (unless (looking-at-p "^[ \t]*$") (save-excursion (insert "\n")))
- (when org-adapt-indentation (indent-to-column col)))
- (org-show-set-visibility 'lineage))
-
-(defun org-agenda-diary-entry ()
- "Make a diary entry, like the `i' command from the calendar.
-All the standard commands work: block, weekly etc.
-When `org-agenda-diary-file' points to a file,
-`org-agenda-diary-entry-in-org-file' is called instead to create
-entries in that Org file."
- (interactive)
- (if (not (eq org-agenda-diary-file 'diary-file))
- (org-agenda-diary-entry-in-org-file)
- (require 'diary-lib)
- (let* ((char (read-char-exclusive
- "Diary entry: [d]ay [w]eekly [m]onthly [y]early\
- [a]nniversary [b]lock [c]yclic"))
- (cmd (cdr (assoc char
- '((?d . diary-insert-entry)
- (?w . diary-insert-weekly-entry)
- (?m . diary-insert-monthly-entry)
- (?y . diary-insert-yearly-entry)
- (?a . diary-insert-anniversary-entry)
- (?b . diary-insert-block-entry)
- (?c . diary-insert-cyclic-entry)))))
- (oldf (symbol-function 'calendar-cursor-to-date))
- ;; (buf (get-file-buffer (substitute-in-file-name diary-file)))
- (point (point))
- (mark (or (mark t) (point))))
- (unless cmd
- (user-error "No command associated with <%c>" char))
- (unless (and (get-text-property point 'day)
- (or (not (equal ?b char))
- (get-text-property mark 'day)))
- (user-error "Don't know which date to use for diary entry"))
- ;; We implement this by hacking the `calendar-cursor-to-date' function
- ;; and the `calendar-mark-ring' variable. Saves a lot of code.
- (let ((calendar-mark-ring
- (list (calendar-gregorian-from-absolute
- (or (get-text-property mark 'day)
- (get-text-property point 'day))))))
- (unwind-protect
- (progn
- (fset 'calendar-cursor-to-date
- (lambda (&optional _error _dummy)
- (calendar-gregorian-from-absolute
- (get-text-property point 'day))))
- (call-interactively cmd))
- (fset 'calendar-cursor-to-date oldf))))))
-
-(defun org-agenda-execute-calendar-command (cmd)
- "Execute a calendar command from the agenda with date from cursor."
- (org-agenda-check-type t 'agenda)
- (require 'diary-lib)
- (unless (get-text-property (min (1- (point-max)) (point)) 'day)
- (user-error "Don't know which date to use for the calendar command"))
- (let* ((oldf (symbol-function 'calendar-cursor-to-date))
- (point (point))
- (date (calendar-gregorian-from-absolute
- (get-text-property point 'day))))
- ;; the following 2 vars are needed in the calendar
- (org-dlet
- ((displayed-month (car date))
- (displayed-year (nth 2 date)))
- (unwind-protect
- (progn
- (fset 'calendar-cursor-to-date
- (lambda (&optional _error _dummy)
- (calendar-gregorian-from-absolute
- (get-text-property point 'day))))
- (call-interactively cmd))
- (fset 'calendar-cursor-to-date oldf)))))
-
-(defun org-agenda-phases-of-moon ()
- "Display the phases of the moon for the 3 months around the cursor date."
- (interactive)
- (org-agenda-execute-calendar-command 'calendar-lunar-phases))
-
-(defun org-agenda-holidays ()
- "Display the holidays for the 3 months around the cursor date."
- (interactive)
- (org-agenda-execute-calendar-command 'calendar-list-holidays))
-
-(defvar calendar-longitude) ; defined in calendar.el
-(defvar calendar-latitude) ; defined in calendar.el
-(defvar calendar-location-name) ; defined in calendar.el
-
-(defun org-agenda-sunrise-sunset (arg)
- "Display sunrise and sunset for the cursor date.
-Latitude and longitude can be specified with the variables
-`calendar-latitude' and `calendar-longitude'. When called with prefix
-argument, latitude and longitude will be prompted for."
- (interactive "P")
- (require 'solar)
- (let ((calendar-longitude (if arg nil calendar-longitude))
- (calendar-latitude (if arg nil calendar-latitude))
- (calendar-location-name
- (if arg "the given coordinates" calendar-location-name)))
- (org-agenda-execute-calendar-command 'calendar-sunrise-sunset)))
-
-(defun org-agenda-goto-calendar ()
- "Open the Emacs calendar with the date at the cursor."
- (interactive)
- (org-agenda-check-type t 'agenda)
- (let* ((day (or (get-text-property (min (1- (point-max)) (point)) 'day)
- (user-error "Don't know which date to open in calendar")))
- (date (calendar-gregorian-from-absolute day))
- (calendar-move-hook nil)
- (calendar-view-holidays-initially-flag nil)
- (calendar-view-diary-initially-flag nil))
- (calendar)
- (calendar-goto-date date)))
-
-;;;###autoload
-(defun org-calendar-goto-agenda ()
- "Compute the Org agenda for the calendar date displayed at the cursor.
-This is a command that has to be installed in `calendar-mode-map'."
- (interactive)
- ;; Temporarily disable sticky agenda since user clearly wants to
- ;; refresh view anyway.
- (let ((org-agenda-buffer-tmp-name "*Org Agenda(a)*")
- (org-agenda-sticky nil))
- (org-agenda-list nil (calendar-absolute-from-gregorian
- (calendar-cursor-to-date))
- nil)))
-
-(defun org-agenda-convert-date ()
- (interactive)
- (org-agenda-check-type t 'agenda)
- (let ((day (get-text-property (min (1- (point-max)) (point)) 'day))
- date s)
- (unless day
- (user-error "Don't know which date to convert"))
- (setq date (calendar-gregorian-from-absolute day))
- (setq s (concat
- "Gregorian: " (calendar-date-string date) "\n"
- "ISO: " (calendar-iso-date-string date) "\n"
- "Day of Yr: " (calendar-day-of-year-string date) "\n"
- "Julian: " (calendar-julian-date-string date) "\n"
- "Astron. JD: " (calendar-astro-date-string date)
- " (Julian date number at noon UTC)\n"
- "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"
- "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"
- "Persian: " (calendar-persian-date-string date) "\n"
- "Chinese: " (calendar-chinese-date-string date) "\n"))
- (with-output-to-temp-buffer "*Dates*"
- (princ s))
- (org-fit-window-to-buffer (get-buffer-window "*Dates*"))))
-
-;;; Bulk commands
-
-(defun org-agenda-bulk-marked-p ()
- "Non-nil when current entry is marked for bulk action."
- (eq (get-char-property (point-at-bol) 'type)
- 'org-marked-entry-overlay))
-
-(defun org-agenda-bulk-mark (&optional arg)
- "Mark entries for future bulk action.
-
-When ARG is nil or one and region is not active then mark the
-entry at point.
-
-When ARG is nil or one and region is active then mark the entries
-in the region.
-
-When ARG is greater than one mark ARG lines."
- (interactive "p")
- (when (and (or (not arg) (= arg 1)) (use-region-p))
- (setq arg (count-lines (region-beginning) (region-end)))
- (goto-char (region-beginning))
- (deactivate-mark))
- (dotimes (_ (or arg 1))
- (unless (org-get-at-bol 'org-agenda-diary-link)
- (let* ((m (org-get-at-bol 'org-hd-marker))
- ov)
- (unless (org-agenda-bulk-marked-p)
- (unless m (user-error "Nothing to mark at point"))
- (push m org-agenda-bulk-marked-entries)
- (setq ov (make-overlay (point-at-bol) (+ 2 (point-at-bol))))
- (org-overlay-display ov (concat org-agenda-bulk-mark-char " ")
- (org-get-todo-face "TODO")
- 'evaporate)
- (overlay-put ov 'type 'org-marked-entry-overlay))
- (end-of-line 1)
- (or (ignore-errors
- (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)))))
- (message "%d entries marked for bulk action"
- (length org-agenda-bulk-marked-entries)))
-
-(defun org-agenda-bulk-mark-all ()
- "Mark all entries for future agenda bulk action."
- (interactive)
- (org-agenda-bulk-mark-regexp "."))
-
-(defun org-agenda-bulk-mark-regexp (regexp)
- "Mark entries matching REGEXP for future agenda bulk action."
- (interactive "sMark entries matching regexp: ")
- (let ((entries-marked 0) txt-at-point)
- (save-excursion
- (goto-char (point-min))
- (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 (match-beginning 0) 'txt)))
- (if (get-char-property (point) 'invisible)
- (beginning-of-line 2)
- (when (string-match-p regexp txt-at-point)
- (setq entries-marked (1+ entries-marked))
- (call-interactively 'org-agenda-bulk-mark)))))
- (unless entries-marked
- (message "No entry matching this regexp."))))
-
-(defun org-agenda-bulk-unmark (&optional arg)
- "Unmark the entry at point for future bulk action."
- (interactive "P")
- (if arg
- (org-agenda-bulk-unmark-all)
- (cond ((org-agenda-bulk-marked-p)
- (org-agenda-bulk-remove-overlays
- (point-at-bol) (+ 2 (point-at-bol)))
- (setq org-agenda-bulk-marked-entries
- (delete (org-get-at-bol 'org-hd-marker)
- org-agenda-bulk-marked-entries))
- (end-of-line 1)
- (or (ignore-errors
- (goto-char (next-single-property-change (point) 'txt)))
- (beginning-of-line 2))
- (while (and (get-char-property (point) 'invisible) (not (eobp)))
- (beginning-of-line 2))
- (message "%d entries left marked for bulk action"
- (length org-agenda-bulk-marked-entries)))
- (t (message "No entry to unmark here")))))
-
-(defun org-agenda-bulk-toggle-all ()
- "Toggle all marks for bulk action."
- (interactive)
- (save-excursion
- (goto-char (point-min))
- (while (ignore-errors
- (goto-char (next-single-property-change (point) 'org-hd-marker)))
- (org-agenda-bulk-toggle))))
-
-(defun org-agenda-bulk-toggle ()
- "Toggle the mark at point for bulk action."
- (interactive)
- (if (org-agenda-bulk-marked-p)
- (org-agenda-bulk-unmark)
- (org-agenda-bulk-mark)))
-
-(defun org-agenda-bulk-remove-overlays (&optional beg end)
- "Remove the mark overlays between BEG and END in the agenda buffer.
-BEG and END default to the buffer limits.
-
-This only removes the overlays, it does not remove the markers
-from the list in `org-agenda-bulk-marked-entries'."
- (interactive)
- (mapc (lambda (ov)
- (and (eq (overlay-get ov 'type) 'org-marked-entry-overlay)
- (delete-overlay ov)))
- (overlays-in (or beg (point-min)) (or end (point-max)))))
-
-(defun org-agenda-bulk-unmark-all ()
- "Remove all marks in the agenda buffer.
-This will remove the markers and the overlays."
- (interactive)
- (if (null org-agenda-bulk-marked-entries)
- (message "No entry to unmark")
- (setq org-agenda-bulk-marked-entries nil)
- (org-agenda-bulk-remove-overlays (point-min) (point-max))))
-
-(defcustom org-agenda-persistent-marks nil
- "Non-nil means marked items will stay marked after a bulk action.
-You can toggle this interactively by typing `p' when prompted for a
-bulk action."
- :group 'org-agenda
- :version "24.1"
- :type 'boolean)
-
-(defcustom org-agenda-loop-over-headlines-in-active-region t
- "Shall some commands act upon headlines in the active region?
-
-When set to t, some commands will be performed in all headlines
-within the active region.
-
-When set to `start-level', some commands will be performed in all
-headlines within the active region, provided that these headlines
-are of the same level than the first one.
-
-When set to a regular expression, those commands will be
-performed on the matching headlines within the active region.
-
-The list of commands is: `org-agenda-schedule',
-`org-agenda-deadline', `org-agenda-date-prompt',
-`org-agenda-todo', `org-agenda-archive*', `org-agenda-kill'.
-
-See `org-loop-over-headlines-in-active-region' for the equivalent
-option for Org buffers."
- :type '(choice (const :tag "Don't loop" nil)
- (const :tag "All headlines in active region" t)
- (const :tag "In active region, headlines at the same level than the first one" start-level)
- (regexp :tag "Regular expression matcher"))
- :version "27.1"
- :package-version '(Org . "9.4")
- :group 'org-agenda)
-
-(defun org-agenda-bulk-action (&optional arg)
- "Execute an remote-editing action on all marked entries.
-The prefix arg is passed through to the command if possible."
- (interactive "P")
- ;; When there is no mark, act on the agenda entry at point.
- (if (not org-agenda-bulk-marked-entries)
- (save-excursion (org-agenda-bulk-mark)))
- (dolist (m org-agenda-bulk-marked-entries)
- (unless (and (markerp m)
- (marker-buffer m)
- (buffer-live-p (marker-buffer m))
- (marker-position m))
- (user-error "Marker %s for bulk command is invalid" m)))
-
- ;; Prompt for the bulk command.
- (org-unlogged-message
- (concat "Bulk (" (if org-agenda-persistent-marks "" "don't ") "[p]ersist marks): "
- "[$]arch [A]rch->sib [t]odo [+/-]tag [s]chd [d]eadline [r]efile "
- "[S]catter [f]unction "
- (and org-agenda-bulk-custom-functions
- (format " Custom: [%s]"
- (mapconcat (lambda (f) (char-to-string (car f)))
- org-agenda-bulk-custom-functions
- "")))))
- (catch 'exit
- (let* ((org-log-refile (if org-log-refile 'time nil))
- (entries (reverse org-agenda-bulk-marked-entries))
- (org-overriding-default-time
- (and (get-text-property (point) 'org-agenda-date-header)
- (org-get-cursor-date)))
- redo-at-end
- cmd)
- (pcase (read-char-exclusive)
- (?p
- (let ((org-agenda-persistent-marks
- (not org-agenda-persistent-marks)))
- (org-agenda-bulk-action)
- (throw 'exit nil)))
-
- (?$
- (setq cmd #'org-agenda-archive))
-
- (?A
- (setq cmd #'org-agenda-archive-to-archive-sibling))
-
- ((or ?r ?w)
- (let ((refile-location
- (org-refile-get-location
- "Refile to"
- (marker-buffer (car entries))
- org-refile-allow-creating-parent-nodes)))
- (when (nth 3 refile-location)
- (setcar (nthcdr 3 refile-location)
- (move-marker
- (make-marker)
- (nth 3 refile-location)
- (or (get-file-buffer (nth 1 refile-location))
- (find-buffer-visiting (nth 1 refile-location))
- (error "This should not happen")))))
-
- (setq cmd (lambda () (org-agenda-refile nil refile-location t)))
- (setq redo-at-end t)))
-
- (?t
- (let ((state (completing-read
- "Todo state: "
- (with-current-buffer (marker-buffer (car entries))
- (mapcar #'list org-todo-keywords-1)))))
- (setq cmd (lambda ()
- (let ((org-inhibit-blocking t)
- (org-inhibit-logging 'note))
- (org-agenda-todo state))))))
-
- ((and (or ?- ?+) action)
- (let ((tag (completing-read
- (format "Tag to %s: " (if (eq action ?+) "add" "remove"))
- (with-current-buffer (marker-buffer (car entries))
- (delq nil
- (mapcar (lambda (x) (and (stringp (car x)) x))
- org-current-tag-alist))))))
- (setq cmd
- (lambda ()
- (org-agenda-set-tags tag
- (if (eq action ?+) 'on 'off))))))
-
- ((and (or ?s ?d) c)
- (let* ((schedule? (eq c ?s))
- (prompt (if schedule? "(Re)Schedule to" "(Re)Set Deadline to"))
- (time
- (and (not arg)
- (let ((new (org-read-date
- nil nil nil prompt org-overriding-default-time)))
- ;; A "double plus" answer applies to every
- ;; scheduled time. Do not turn it into
- ;; a fixed date yet.
- (if (string-match-p "\\`[ \t]*\\+\\+"
- org-read-date-final-answer)
- org-read-date-final-answer
- new)))))
- ;; Make sure to not prompt for a note when bulk
- ;; rescheduling/resetting deadline as Org cannot cope with
- ;; simultaneous notes. Besides, it could be annoying
- ;; depending on the number of marked items.
- (setq cmd
- (if schedule?
- (lambda ()
- (let ((org-log-reschedule
- (and org-log-reschedule 'time)))
- (org-agenda-schedule arg time)))
- (lambda ()
- (let ((org-log-redeadline (and org-log-redeadline 'time)))
- (org-agenda-deadline arg time)))))))
-
- (?S
- (unless (org-agenda-check-type nil 'agenda 'todo)
- (user-error "Can't scatter tasks in \"%s\" agenda view" org-agenda-type))
- (let ((days (read-number
- (format "Scatter tasks across how many %sdays: "
- (if arg "week" ""))
- 7)))
- (setq cmd
- (lambda ()
- (let ((distance (1+ (random days))))
- (when arg
- (let ((dist distance)
- (day-of-week
- (calendar-day-of-week
- (calendar-gregorian-from-absolute (org-today)))))
- (dotimes (_ (1+ dist))
- (while (member day-of-week org-agenda-weekend-days)
- (cl-incf distance)
- (cl-incf day-of-week)
- (when (= day-of-week 7)
- (setq day-of-week 0)))
- (cl-incf day-of-week)
- (when (= day-of-week 7)
- (setq day-of-week 0)))))
- ;; Silently fail when try to replan a sexp entry.
- (ignore-errors
- (let* ((date (calendar-gregorian-from-absolute
- (+ (org-today) distance)))
- (time (encode-time 0 0 0 (nth 1 date) (nth 0 date)
- (nth 2 date))))
- (org-agenda-schedule nil time))))))))
-
- (?f
- (setq cmd
- (intern
- (completing-read "Function: " obarray #'fboundp t nil nil))))
-
- (action
- (setq cmd
- (pcase (assoc action org-agenda-bulk-custom-functions)
- (`(,_ ,fn)
- fn)
- (`(,_ ,fn ,arg-fn)
- (apply #'apply-partially fn (funcall arg-fn)))
- (_
- (user-error "Invalid bulk action: %c" action))))
- (setq redo-at-end t)))
- ;; Sort the markers, to make sure that parents are handled
- ;; before children.
- (setq entries (sort entries
- (lambda (a b)
- (cond
- ((eq (marker-buffer a) (marker-buffer b))
- (< (marker-position a) (marker-position b)))
- (t
- (string< (buffer-name (marker-buffer a))
- (buffer-name (marker-buffer b))))))))
-
- ;; Now loop over all markers and apply CMD.
- (let ((processed 0)
- (skipped 0))
- (dolist (e entries)
- (let ((pos (text-property-any (point-min) (point-max) 'org-hd-marker e)))
- (if (not pos)
- (progn (message "Skipping removed entry at %s" e)
- (cl-incf skipped))
- (goto-char pos)
- (let (org-loop-over-headlines-in-active-region) (funcall cmd))
- ;; `post-command-hook' is not run yet. We make sure any
- ;; pending log note is processed.
- (when org-log-setup (org-add-log-note))
- (cl-incf processed))))
- (when redo-at-end (org-agenda-redo))
- (unless org-agenda-persistent-marks (org-agenda-bulk-unmark-all))
- (message "Acted on %d entries%s%s"
- processed
- (if (= skipped 0)
- ""
- (format ", skipped %d (disappeared before their turn)"
- skipped))
- (if (not org-agenda-persistent-marks) "" " (kept marked)"))))))
-
-(defun org-agenda-capture (&optional with-time)
- "Call `org-capture' with the date at point.
-With a `C-1' prefix, use the HH:MM value at point (if any) or the
-current HH:MM time."
- (interactive "P")
- (if (not (eq major-mode 'org-agenda-mode))
- (user-error "You cannot do this outside of agenda buffers")
- (let ((org-overriding-default-time
- (org-get-cursor-date (equal with-time 1))))
- (call-interactively 'org-capture))))
-
-;;; Dragging agenda lines forward/backward
-
-(defun org-agenda-reapply-filters ()
- "Re-apply all agenda filters."
- (mapcar
- (lambda(f) (when (car f) (org-agenda-filter-apply (car f) (cadr f) t)))
- `((,org-agenda-tag-filter tag)
- (,org-agenda-category-filter category)
- (,org-agenda-regexp-filter regexp)
- (,org-agenda-effort-filter effort)
- (,(get 'org-agenda-tag-filter :preset-filter) tag)
- (,(get 'org-agenda-category-filter :preset-filter) category)
- (,(get 'org-agenda-effort-filter :preset-filter) effort)
- (,(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 line)
- (if (or (not (get-text-property (point) 'txt))
- (save-excursion
- (dotimes (_ arg)
- (move-beginning-of-line (if backward 0 2))
- (push (not (get-text-property (point) 'txt)) lst))
- (delq nil lst)))
- (message "Cannot move line forward")
- (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")
- (org-agenda-drag-line-forward arg t))
-
-;;; Flagging notes
-
-(defun org-agenda-show-the-flagging-note ()
- "Display the flagging note in the other window.
-When called a second time in direct sequence, offer to remove the FLAGGING
-tag and (if present) the flagging note."
- (interactive)
- (let ((hdmarker (org-get-at-bol 'org-hd-marker))
- (win (selected-window))
- note) ;; heading newhead
- (unless hdmarker
- (user-error "No linked entry at point"))
- (if (and (eq this-command last-command)
- (y-or-n-p "Unflag and remove any flagging note? "))
- (progn
- (org-agenda-remove-flag hdmarker)
- (let ((win (get-buffer-window "*Flagging Note*")))
- (and win (delete-window win)))
- (message "Entry unflagged"))
- (setq note (org-entry-get hdmarker "THEFLAGGINGNOTE"))
- (unless note
- (user-error "No flagging note"))
- (org-kill-new note)
- (org-switch-to-buffer-other-window "*Flagging Note*")
- (erase-buffer)
- (insert note)
- (goto-char (point-min))
- (while (re-search-forward "\\\\n" nil t)
- (replace-match "\n" t t))
- (goto-char (point-min))
- (select-window win)
- (message "%s" (substitute-command-keys "Flagging note pushed to \
-kill ring. Press `\\[org-agenda-show-the-flagging-note]' again to remove \
-tag and note")))))
-
-(defun org-agenda-remove-flag (marker)
- "Remove the FLAGGED tag and any flagging note in the entry."
- (let ((newhead
- (org-with-point-at marker
- (org-toggle-tag "FLAGGED" 'off)
- (org-entry-delete nil "THEFLAGGINGNOTE")
- (org-get-heading))))
- (org-agenda-change-all-lines newhead marker)
- (message "Entry unflagged")))
-
-(defun org-agenda-get-any-marker (&optional pos)
- (or (get-text-property (or pos (point-at-bol)) 'org-hd-marker)
- (get-text-property (or pos (point-at-bol)) 'org-marker)))
-
-;;; Appointment reminders
-
-(defvar appt-time-msg-list) ; defined in appt.el
-
-;;;###autoload
-(defun org-agenda-to-appt (&optional refresh filter &rest args)
- "Activate appointments found in `org-agenda-files'.
-
-With a `\\[universal-argument]' prefix, refresh the list of \
-appointments.
-
-If FILTER is t, interactively prompt the user for a regular
-expression, and filter out entries that don't match it.
-
-If FILTER is a string, use this string as a regular expression
-for filtering entries out.
-
-If FILTER is a function, filter out entries against which
-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:
-
- \\='((headline \"IMPORTANT\")
- (category \"Work\"))
-
-will only add headlines containing IMPORTANT or headlines
-belonging to the \"Work\" category.
-
-ARGS are symbols indicating what kind of entries to consider.
-By default `org-agenda-to-appt' will use :deadline*, :scheduled*
-\(i.e., deadlines and scheduled items with a hh:mm specification)
-and :timestamp entries. See the docstring of `org-diary' for
-details and examples.
-
-If an entry has a APPT_WARNTIME property, its value will be used
-to override `appt-message-warning-time'."
- (interactive "P")
- (when refresh (setq appt-time-msg-list nil))
- (when (eq filter t)
- (setq filter (read-from-minibuffer "Regexp filter: ")))
- (let* ((cnt 0) ; count added events
- (scope (or args '(:deadline* :scheduled* :timestamp)))
- (org-agenda-new-buffers nil)
- (org-deadline-warning-days 0)
- ;; Do not use `org-today' here because appt only takes
- ;; time and without date as argument, so it may pass wrong
- ;; information otherwise
- (today (org-date-to-gregorian
- (time-to-days nil)))
- (org-agenda-restrict nil)
- (files (org-agenda-files 'unrestricted)) entries file
- (org-agenda-buffer nil))
- ;; Get all entries which may contain an appt
- (org-agenda-prepare-buffers files)
- (while (setq file (pop files))
- (setq entries
- (delq nil
- (append entries
- (apply #'org-agenda-get-day-entries
- file today scope)))))
- ;; Map through entries and find if we should filter them out
- (mapc
- (lambda (x)
- (let* ((evt (org-trim
- (replace-regexp-in-string
- org-link-bracket-re "\\2"
- (or (get-text-property 1 'txt x) ""))))
- (cat (get-text-property (1- (length x)) 'org-category x))
- (tod (get-text-property 1 'time-of-day x))
- (ok (or (null filter)
- (and (stringp filter) (string-match filter evt))
- (and (functionp filter) (funcall filter x))
- (and (listp filter)
- (let ((cat-filter (cadr (assq 'category filter)))
- (evt-filter (cadr (assq 'headline filter))))
- (or (and (stringp cat-filter)
- (string-match cat-filter cat))
- (and (stringp evt-filter)
- (string-match evt-filter evt)))))))
- (wrn (get-text-property 1 'warntime x)))
- ;; FIXME: Shall we remove text-properties for the appt text?
- ;; (setq evt (set-text-properties 0 (length evt) nil evt))
- (when (and ok tod (not (string-match "\\`DONE\\|CANCELLED" evt)))
- (setq tod (concat "00" (number-to-string tod)))
- (setq tod (when (string-match
- "\\([0-9]\\{1,2\\}\\)\\([0-9]\\{2\\}\\)\\'" tod)
- (concat (match-string 1 tod) ":"
- (match-string 2 tod))))
- (when (appt-add tod evt wrn)
- (setq cnt (1+ cnt))))))
- entries)
- (org-release-buffers org-agenda-new-buffers)
- (if (eq cnt 0)
- (message "No event to add")
- (message "Added %d event%s for today" cnt (if (> cnt 1) "s" "")))))
-
-(defun org-agenda-today-p (date)
- "Non-nil when DATE means today.
-DATE is either a list of the form (month day year) or a number of
-days as returned by `calendar-absolute-from-gregorian' or
-`org-today'. This function considers `org-extend-today-until'
-when defining today."
- (eq (org-today)
- (if (consp date) (calendar-absolute-from-gregorian date) date)))
-
-(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* ((org-use-effective-time t)
- (hour (nth 2 (decode-time (org-current-time))))
- (org-extend-today-until (1+ hour)))
- (org-agenda-todo arg)))
-
-(defun org-agenda-ctrl-c-ctrl-c ()
- "Set tags in agenda buffer."
- (interactive)
- (org-agenda-set-tags))
-
-(provide 'org-agenda)
-
-;;; org-agenda.el ends here