Merge branch 'max-sticky-agenda'

This commit is contained in:
Max Mikhanosha 2012-04-16 05:25:06 -04:00
commit 973efcd9c9
2 changed files with 450 additions and 232 deletions

View File

@ -7245,6 +7245,16 @@ the region. Otherwise, restrict it to the current subtree@footnote{For
backward compatibility, you can also press @kbd{0} to restrict to the backward compatibility, you can also press @kbd{0} to restrict to the
current region/subtree.}. After pressing @kbd{< <}, you still need to press the current region/subtree.}. After pressing @kbd{< <}, you still need to press the
character selecting the command. character selecting the command.
@item *
@vindex org-agenda-sticky
Toggle sticky agenda views. By default, Org maintains only a single agenda
buffer and rebuilds it each time you change the view, to make sure everything
is always up to date. If you switch between views often and the build time
bothers you, you can turn on sticky agenda buffers (make this the default by
customizing the variable @code{org-agenda-sticky}). With sticky agendas, the
dispatcher only switches to the selected view, you need to update it by hand
with @kbd{r} or @kbd{g}.
@end table @end table
You can also define custom commands that will be accessible through the You can also define custom commands that will be accessible through the

View File

@ -934,7 +934,8 @@ have been removed when this is called, as will any matches for regular
expressions listed in `org-agenda-entry-text-exclude-regexps'.") expressions listed in `org-agenda-entry-text-exclude-regexps'.")
(defvar org-agenda-include-inactive-timestamps nil (defvar org-agenda-include-inactive-timestamps nil
"Non-nil means include inactive time stamps in agenda and timeline.") "Non-nil means include inactive time stamps in agenda and timeline.
Dynamically scoped.")
(defgroup org-agenda-windows nil (defgroup org-agenda-windows nil
"Options concerning the windows used by the Agenda in Org Mode." "Options concerning the windows used by the Agenda in Org Mode."
@ -1503,8 +1504,10 @@ Custom commands can set this variable in the options section."
:group 'org-agenda-line-format) :group 'org-agenda-line-format)
(defvar org-prefix-format-compiled nil (defvar org-prefix-format-compiled nil
"The compiled version of the most recently used prefix format. "The compiled prefix format and associated variables.
See the variable `org-agenda-prefix-format'.") 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" (defcustom org-agenda-todo-keyword-format "%-1s"
"Format for the TODO keyword in agenda lines. "Format for the TODO keyword in agenda lines.
@ -1812,6 +1815,72 @@ works you probably want to add it to `org-agenda-custom-commands' for good."
(defvar org-agenda-force-single-file nil) (defvar org-agenda-force-single-file nil)
(defvar org-agenda-bulk-marked-entries) ;; Defined further down in this file (defvar org-agenda-bulk-marked-entries) ;; Defined further down in this file
;;; Multiple agenda buffers support
(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)
(message "Sticky agenda was already %s"
(if org-agenda-sticky "enabled" "disabled"))
(setq org-agenda-sticky new-value)
(org-agenda-kill-all-agenda-buffers)
(message "Sticky agenda was %s"
(if org-agenda-sticky "enabled" "disabled")))))
(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
:type 'boolean
:set (lambda (var val)
(if (boundp var)
(org-toggle-sticky-agenda (if val 1 0))
(set var val))))
(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)
(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-last-arguments
org-agenda-info
org-agenda-tag-filter-overlays
org-agenda-cat-filter-overlays
org-pre-agenda-window-conf
org-agenda-columns-active
org-agenda-tag-filter
org-agenda-category-filter
org-agenda-markers
org-agenda-last-search-view-search-was-boolean
org-agenda-filtered-by-category
org-agenda-filter-form
org-agenda-show-window
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 () (defun org-agenda-mode ()
"Mode for time-sorted view on action items in Org-mode files. "Mode for time-sorted view on action items in Org-mode files.
@ -1819,7 +1888,30 @@ The following commands are available:
\\{org-agenda-mode-map}" \\{org-agenda-mode-map}"
(interactive) (interactive)
(kill-all-local-variables) (cond (org-agenda-doing-sticky-redo
;; Refreshing sticky agenda-buffer
;;
;; Preserve the value of `org-agenda-local-vars' variables,
;; while letting `kill-all-local-variables' kill the rest
(let ((save (buffer-local-variables)))
(kill-all-local-variables)
(mapc 'make-local-variable org-agenda-local-vars)
(dolist (elem save)
(let ((var (car elem))
(val (cdr elem)))
(when (and val
(member var org-agenda-local-vars))
(set var val)))))
(set (make-local-variable 'org-agenda-this-buffer-is-sticky) t))
(org-agenda-sticky
;; Creating a sticky Agenda buffer for the first time
(kill-all-local-variables)
(mapc 'make-local-variable org-agenda-local-vars)
(set (make-local-variable 'org-agenda-this-buffer-is-sticky) t))
(t
;; Creating a non-sticky agenda buffer
(kill-all-local-variables)
(set (make-local-variable 'org-agenda-this-buffer-is-sticky) nil)))
(setq org-agenda-undo-list nil (setq org-agenda-undo-list nil
org-agenda-pending-undo-list nil org-agenda-pending-undo-list nil
org-agenda-bulk-marked-entries nil) org-agenda-bulk-marked-entries nil)
@ -1933,6 +2025,7 @@ The following commands are available:
'org-clock-modify-effort-estimate) '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 "\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 "Q" 'org-agenda-Quit)
(org-defkey org-agenda-mode-map "x" 'org-agenda-exit) (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-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 "\C-x\C-s" 'org-save-all-org-buffers)
@ -2238,6 +2331,7 @@ Pressing `<' twice means to restrict to the current subtree or region
(interactive "P") (interactive "P")
(catch 'exit (catch 'exit
(let* ((prefix-descriptions nil) (let* ((prefix-descriptions nil)
(org-agenda-buffer-name org-agenda-buffer-name)
(org-agenda-window-setup (if (equal (buffer-name) (org-agenda-window-setup (if (equal (buffer-name)
org-agenda-buffer-name) org-agenda-buffer-name)
'current-window 'current-window
@ -2276,6 +2370,11 @@ Pressing `<' twice means to restrict to the current subtree or region
(setq ans (org-agenda-get-restriction-and-command prefix-descriptions) (setq ans (org-agenda-get-restriction-and-command prefix-descriptions)
keys (car ans) keys (car ans)
restriction (cdr 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.
(if org-agenda-sticky
(setq org-agenda-buffer-name (format "*Org Agenda(%s)*" keys)))
;; Establish the restriction, if any ;; Establish the restriction, if any
(when (and (not org-agenda-overriding-restriction) restriction) (when (and (not org-agenda-overriding-restriction) restriction)
(put 'org-agenda-files 'org-restrict (list bfn)) (put 'org-agenda-files 'org-restrict (list bfn))
@ -2408,15 +2507,15 @@ Agenda views are separated by `org-agenda-block-separator'."
(erase-buffer) (erase-buffer)
(insert (eval-when-compile (insert (eval-when-compile
(let ((header (let ((header
" "Press key for an agenda command: < Buffer, subtree/region restriction
Press key for an agenda command: < Buffer, subtree/region restriction
-------------------------------- > Remove restriction -------------------------------- > Remove restriction
a Agenda for current week or day e Export agenda views a Agenda for current week or day e Export agenda views
t List of all TODO entries T Entries with special TODO kwd t List of all TODO entries T Entries with special TODO kwd
m Match a TAGS/PROP/TODO query M Like m, but only TODO entries m Match a TAGS/PROP/TODO query M Like m, but only TODO entries
L Timeline for current buffer # List stuck projects (!=configure) L Timeline for current buffer # List stuck projects (!=configure)
s Search for keywords C Configure custom agenda commands s Search for keywords * Toggle sticky agenda views
/ Multi-occur ? Find :FLAGGED: entries / Multi-occur ? Find :FLAGGED: entries
C Configure custom agenda commands
") ")
(start 0)) (start 0))
(while (string-match (while (string-match
@ -2549,6 +2648,9 @@ s Search for keywords C Configure custom agenda commands
nil nil
(cons (substring (car x) 1) (cdr x)))) (cons (substring (car x) 1) (cdr x))))
custom)))) custom))))
((eq c ?*)
(org-toggle-sticky-agenda)
(sit-for 2))
((and (not restrict-ok) (memq c '(?1 ?0 ?<))) ((and (not restrict-ok) (memq c '(?1 ?0 ?<)))
(message "Restriction is only possible in Org-mode buffers") (message "Restriction is only possible in Org-mode buffers")
(ding) (sit-for 1)) (ding) (sit-for 1))
@ -2584,6 +2686,9 @@ s Search for keywords C Configure custom agenda commands
"The arguments of the previous call to `org-agenda'.") "The arguments of the previous call to `org-agenda'.")
(defun org-agenda-run-series (name series) (defun org-agenda-run-series (name series)
(org-let (nth 1 series) '(org-prepare-agenda name)) (org-let (nth 1 series) '(org-prepare-agenda 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)
(let* ((org-agenda-multi t) (let* ((org-agenda-multi t)
(redo (list 'org-agenda-run-series name (list 'quote series))) (redo (list 'org-agenda-run-series name (list 'quote series)))
(org-agenda-overriding-arguments (org-agenda-overriding-arguments
@ -3094,61 +3199,101 @@ 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 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.") the global options and expect it to be applied to the entire view.")
(defun org-agenda-use-sticky-p ()
"Return non-NIL if existing 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))))
(defun org-prepare-agenda-window (abuf)
"Setup agenda buffer in the window"
(let* ((awin (get-buffer-window abuf))
wconf)
(cond
((equal (current-buffer) abuf) nil)
(awin (select-window awin))
((not (setq wconf (current-window-configuration))))
((equal org-agenda-window-setup 'current-window)
(org-pop-to-buffer-same-window abuf))
((equal org-agenda-window-setup 'other-window)
(org-switch-to-buffer-other-window abuf))
((equal org-agenda-window-setup 'other-frame)
(switch-to-buffer-other-frame abuf))
((equal org-agenda-window-setup 'reorganize-frame)
(delete-other-windows)
(org-switch-to-buffer-other-window abuf)))
;; additional test in case agenda is invoked from within agenda
;; buffer via elisp link
(unless (equal (current-buffer) abuf)
(org-pop-to-buffer-same-window abuf))
(setq org-pre-agenda-window-conf wconf)))
(defun org-prepare-agenda (&optional name) (defun org-prepare-agenda (&optional name)
(setq org-todo-keywords-for-agenda nil) (if (org-agenda-use-sticky-p)
(setq org-drawers-for-agenda nil)
(unless org-agenda-persistent-filter
(setq org-agenda-tag-filter nil
org-agenda-category-filter nil))
(put 'org-agenda-tag-filter :preset-filter org-agenda-tag-filter-preset)
(put 'org-agenda-category-filter :preset-filter org-agenda-category-filter-preset)
(if org-agenda-multi
(progn (progn
(setq buffer-read-only nil) ;; Popup existing buffer
(goto-char (point-max)) (org-prepare-agenda-window (get-buffer org-agenda-buffer-name))
(unless (or (bobp) org-agenda-compact-blocks (message "Sticky Agenda buffer, use `r' to refresh")
(not org-agenda-block-separator)) (throw 'exit nil))
(insert "\n" (setq org-todo-keywords-for-agenda nil)
(if (stringp org-agenda-block-separator) (setq org-drawers-for-agenda nil)
org-agenda-block-separator (unless org-agenda-persistent-filter
(make-string (window-width) org-agenda-block-separator)) (setq org-agenda-tag-filter nil
"\n")) org-agenda-category-filter nil))
(narrow-to-region (point) (point-max))) (put 'org-agenda-tag-filter :preset-filter org-agenda-tag-filter-preset)
(setq org-done-keywords-for-agenda nil) (put 'org-agenda-category-filter :preset-filter
(org-agenda-reset-markers) org-agenda-category-filter-preset)
(setq org-agenda-contributing-files nil) (if org-agenda-multi
(setq org-agenda-columns-active nil) (progn
(org-prepare-agenda-buffers (org-agenda-files nil 'ifmode)) (setq buffer-read-only nil)
(setq org-todo-keywords-for-agenda (goto-char (point-max))
(org-uniquify org-todo-keywords-for-agenda)) (unless (or (bobp) org-agenda-compact-blocks
(setq org-done-keywords-for-agenda (not org-agenda-block-separator))
(org-uniquify org-done-keywords-for-agenda)) (insert "\n"
(setq org-drawers-for-agenda (org-uniquify org-drawers-for-agenda)) (if (stringp org-agenda-block-separator)
(let* ((abuf (get-buffer-create org-agenda-buffer-name)) org-agenda-block-separator
(awin (get-buffer-window abuf))) (make-string (window-width) org-agenda-block-separator))
(cond "\n"))
((equal (current-buffer) abuf) nil) (narrow-to-region (point) (point-max)))
(awin (select-window awin)) (setq org-done-keywords-for-agenda nil)
((not (setq org-pre-agenda-window-conf (current-window-configuration))))
((equal org-agenda-window-setup 'current-window) ;; Setting any org variables that are in org-agenda-local-vars
(org-pop-to-buffer-same-window abuf)) ;; list need to be done after the prepare call
((equal org-agenda-window-setup 'other-window) (org-prepare-agenda-window (get-buffer-create org-agenda-buffer-name))
(org-switch-to-buffer-other-window abuf)) (setq buffer-read-only nil)
((equal org-agenda-window-setup 'other-frame) (org-agenda-reset-markers)
(switch-to-buffer-other-frame abuf)) (let ((inhibit-read-only t)) (erase-buffer))
((equal org-agenda-window-setup 'reorganize-frame) (org-agenda-mode)
(delete-other-windows) (setq org-agenda-buffer (current-buffer))
(org-switch-to-buffer-other-window abuf))) (setq org-agenda-contributing-files nil)
;; additional test in case agenda is invoked from within agenda (setq org-agenda-columns-active nil)
;; buffer via elisp link (org-prepare-agenda-buffers (org-agenda-files nil 'ifmode))
(unless (equal (current-buffer) abuf) (setq org-todo-keywords-for-agenda
(org-pop-to-buffer-same-window abuf))) (org-uniquify org-todo-keywords-for-agenda))
(setq buffer-read-only nil) (setq org-done-keywords-for-agenda
(let ((inhibit-read-only t)) (erase-buffer)) (org-uniquify org-done-keywords-for-agenda))
(org-agenda-mode) (setq org-drawers-for-agenda (org-uniquify org-drawers-for-agenda))
(and name (not org-agenda-name) (setq org-agenda-last-prefix-arg current-prefix-arg)
(org-set-local 'org-agenda-name name))) (setq org-agenda-this-buffer-name org-agenda-buffer-name)
(setq buffer-read-only nil)) (and name (not org-agenda-name)
(org-set-local 'org-agenda-name name)))
(setq buffer-read-only nil)))
(defun org-finalize-agenda () (defun org-finalize-agenda ()
"Finishing touch for the agenda buffer, called just before displaying it." "Finishing touch for the agenda buffer, called just before displaying it."
@ -3185,6 +3330,7 @@ the global options and expect it to be applied to the entire view.")
(org-agenda-filter-apply org-agenda-tag-filter 'tag)) (org-agenda-filter-apply org-agenda-tag-filter 'tag))
(when (or org-agenda-category-filter (get 'org-agenda-category-filter :preset-filter)) (when (or org-agenda-category-filter (get 'org-agenda-category-filter :preset-filter))
(org-agenda-filter-apply org-agenda-category-filter 'category)) (org-agenda-filter-apply org-agenda-category-filter 'category))
(org-add-hook 'kill-buffer-hook 'org-agenda-reset-markers 'append 'local)
))) )))
(defun org-agenda-mark-clocking-task () (defun org-agenda-mark-clocking-task ()
@ -3330,7 +3476,8 @@ Org-mode keeps a list of these markers and resets them when they are
no longer in use." no longer in use."
(let ((m (copy-marker (or pos (point))))) (let ((m (copy-marker (or pos (point)))))
(setq org-agenda-last-marker-time (org-float-time)) (setq org-agenda-last-marker-time (org-float-time))
(push m org-agenda-markers) (with-current-buffer org-agenda-buffer
(push m org-agenda-markers))
m)) m))
(defun org-agenda-reset-markers () (defun org-agenda-reset-markers ()
@ -3339,9 +3486,13 @@ no longer in use."
(move-marker (pop org-agenda-markers) nil))) (move-marker (pop org-agenda-markers) nil)))
(defun org-agenda-save-markers-for-cut-and-paste (beg end) (defun org-agenda-save-markers-for-cut-and-paste (beg end)
"Save relative positions of markers in region." "Save relative positions of markers in region.
(mapc (lambda (m) (org-check-and-save-marker m beg end)) This check for agenda markers in all agenda buffers currently active."
org-agenda-markers)) (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 ;;; Entry text mode
@ -3402,18 +3553,17 @@ under the current date.
If the buffer contains an active region, only check the region for If the buffer contains an active region, only check the region for
dates." dates."
(interactive "P") (interactive "P")
(org-compile-prefix-format 'timeline)
(org-set-sorting-strategy 'timeline)
(let* ((dopast t) (let* ((dopast t)
(doclosed org-agenda-show-log) (org-agenda-show-log-scoped org-agenda-show-log)
(entry (buffer-file-name (or (buffer-base-buffer (current-buffer)) (entry (buffer-file-name (or (buffer-base-buffer (current-buffer))
(current-buffer)))) (current-buffer))))
(date (calendar-current-date)) (date (calendar-current-date))
(beg (if (org-region-active-p) (region-beginning) (point-min))) (beg (if (org-region-active-p) (region-beginning) (point-min)))
(end (if (org-region-active-p) (region-end) (point-max))) (end (if (org-region-active-p) (region-end) (point-max)))
(day-numbers (org-get-all-dates beg end 'no-ranges (day-numbers (org-get-all-dates
t doclosed ; always include today beg end 'no-ranges
org-timeline-show-empty-dates)) t org-agenda-show-log-scoped ; always include today
org-timeline-show-empty-dates))
(org-deadline-warning-days 0) (org-deadline-warning-days 0)
(org-agenda-only-exact-dates t) (org-agenda-only-exact-dates t)
(today (org-today)) (today (org-today))
@ -3430,7 +3580,9 @@ dates."
(if (>= x today) x nil)) (if (>= x today) x nil))
day-numbers)))) day-numbers))))
(org-prepare-agenda (concat "Timeline " (file-name-nondirectory entry))) (org-prepare-agenda (concat "Timeline " (file-name-nondirectory entry)))
(if doclosed (push :closed args)) (org-compile-prefix-format 'timeline)
(org-set-sorting-strategy 'timeline)
(if org-agenda-show-log-scoped (push :closed args))
(push :timestamp args) (push :timestamp args)
(push :deadline args) (push :deadline args)
(push :scheduled args) (push :scheduled args)
@ -3585,6 +3737,7 @@ given in `org-agenda-start-on-weekday'."
(interactive "P") (interactive "P")
(if (and (integerp arg) (> arg 0)) (if (and (integerp arg) (> arg 0))
(setq span arg arg nil)) (setq span arg arg nil))
(org-prepare-agenda "Day/Week")
(setq start-day (or start-day org-agenda-start-day)) (setq start-day (or start-day org-agenda-start-day))
(if org-agenda-overriding-arguments (if org-agenda-overriding-arguments
(setq arg (car org-agenda-overriding-arguments) (setq arg (car org-agenda-overriding-arguments)
@ -3617,6 +3770,7 @@ given in `org-agenda-start-on-weekday'."
(day-numbers (list start)) (day-numbers (list start))
(day-cnt 0) (day-cnt 0)
(inhibit-redisplay (not debug-on-error)) (inhibit-redisplay (not debug-on-error))
(org-agenda-show-log-scoped org-agenda-show-log)
s e rtn rtnall file date d start-pos end-pos todayp s e rtn rtnall file date d start-pos end-pos todayp
clocktable-start clocktable-end filter) clocktable-start clocktable-end filter)
(setq org-agenda-redo-command (setq org-agenda-redo-command
@ -3626,7 +3780,6 @@ given in `org-agenda-start-on-weekday'."
(setq day-numbers (nreverse day-numbers)) (setq day-numbers (nreverse day-numbers))
(setq clocktable-start (car day-numbers) (setq clocktable-start (car day-numbers)
clocktable-end (1+ (or (org-last day-numbers) 0))) clocktable-end (1+ (or (org-last day-numbers) 0)))
(org-prepare-agenda "Day/Week")
(org-set-local 'org-starting-day (car day-numbers)) (org-set-local 'org-starting-day (car day-numbers))
(org-set-local 'org-arg-loc arg) (org-set-local 'org-arg-loc arg)
(org-set-local 'org-agenda-current-span (org-agenda-ndays-to-span span)) (org-set-local 'org-agenda-current-span (org-agenda-ndays-to-span span))
@ -3668,10 +3821,10 @@ given in `org-agenda-start-on-weekday'."
(setq org-agenda-entry-types (setq org-agenda-entry-types
(delq :deadline org-agenda-entry-types))) (delq :deadline org-agenda-entry-types)))
(cond (cond
((memq org-agenda-show-log '(only clockcheck)) ((memq org-agenda-show-log-scoped '(only clockcheck))
(setq rtn (org-agenda-get-day-entries (setq rtn (org-agenda-get-day-entries
file date :closed))) file date :closed)))
(org-agenda-show-log (org-agenda-show-log-scoped
(setq rtn (apply 'org-agenda-get-day-entries (setq rtn (apply 'org-agenda-get-day-entries
file date file date
(append '(:closed) org-agenda-entry-types)))) (append '(:closed) org-agenda-entry-types))))
@ -3739,7 +3892,7 @@ given in `org-agenda-start-on-weekday'."
(recenter 1)))) (recenter 1))))
(goto-char (or start-pos 1)) (goto-char (or start-pos 1))
(add-text-properties (point-min) (point-max) '(org-agenda-type agenda)) (add-text-properties (point-min) (point-max) '(org-agenda-type agenda))
(if (eq org-agenda-show-log 'clockcheck) (if (eq org-agenda-show-log-scoped 'clockcheck)
(org-agenda-show-clocking-issues)) (org-agenda-show-clocking-issues))
(org-finalize-agenda) (org-finalize-agenda)
(setq buffer-read-only t) (setq buffer-read-only t)
@ -3836,9 +3989,9 @@ as a whole, to include whitespace.
This command searches the agenda files, and in addition the files listed This command searches the agenda files, and in addition the files listed
in `org-agenda-text-search-extra-files'." in `org-agenda-text-search-extra-files'."
(interactive "P") (interactive "P")
(org-prepare-agenda "SEARCH")
(org-compile-prefix-format 'search) (org-compile-prefix-format 'search)
(org-set-sorting-strategy 'search) (org-set-sorting-strategy 'search)
(org-prepare-agenda "SEARCH")
(let* ((props (list 'face nil (let* ((props (list 'face nil
'done-face 'org-agenda-done 'done-face 'org-agenda-done
'org-not-done-regexp org-not-done-regexp 'org-not-done-regexp org-not-done-regexp
@ -4047,9 +4200,9 @@ the list to these. When using \\[universal-argument], you will be prompted
for a keyword. A numeric prefix directly selects the Nth keyword in for a keyword. A numeric prefix directly selects the Nth keyword in
`org-todo-keywords-1'." `org-todo-keywords-1'."
(interactive "P") (interactive "P")
(org-prepare-agenda "TODO")
(org-compile-prefix-format 'todo) (org-compile-prefix-format 'todo)
(org-set-sorting-strategy 'todo) (org-set-sorting-strategy 'todo)
(org-prepare-agenda "TODO")
(if (and (stringp arg) (not (string-match "\\S-" arg))) (setq arg nil)) (if (and (stringp arg) (not (string-match "\\S-" arg))) (setq arg nil))
(let* ((today (org-today)) (let* ((today (org-today))
(date (calendar-gregorian-from-absolute today)) (date (calendar-gregorian-from-absolute today))
@ -4063,7 +4216,7 @@ for a keyword. A numeric prefix directly selects the Nth keyword in
(when (equal arg '(4)) (when (equal arg '(4))
(setq org-select-this-todo-keyword (setq org-select-this-todo-keyword
(org-icompleting-read "Keyword (or KWD1|K2D2|...): " (org-icompleting-read "Keyword (or KWD1|K2D2|...): "
(mapcar 'list kwds) nil nil))) (mapcar 'list kwds) nil nil)))
(and (equal 0 arg) (setq org-select-this-todo-keyword nil)) (and (equal 0 arg) (setq org-select-this-todo-keyword nil))
(org-set-local 'org-last-arg arg) (org-set-local 'org-last-arg arg)
(setq org-agenda-redo-command (setq org-agenda-redo-command
@ -4116,8 +4269,6 @@ for a keyword. A numeric prefix directly selects the Nth keyword in
"Show all headlines for all `org-agenda-files' matching a TAGS criterion. "Show all headlines for all `org-agenda-files' matching a TAGS criterion.
The prefix arg TODO-ONLY limits the search to TODO entries." The prefix arg TODO-ONLY limits the search to TODO entries."
(interactive "P") (interactive "P")
(org-compile-prefix-format 'tags)
(org-set-sorting-strategy 'tags)
(let* ((org-tags-match-list-sublevels (let* ((org-tags-match-list-sublevels
org-tags-match-list-sublevels) org-tags-match-list-sublevels)
(completion-ignore-case t) (completion-ignore-case t)
@ -4128,6 +4279,8 @@ The prefix arg TODO-ONLY limits the search to TODO entries."
(setq matcher (org-make-tags-matcher match) (setq matcher (org-make-tags-matcher match)
match (car matcher) matcher (cdr matcher)) match (car matcher) matcher (cdr matcher))
(org-prepare-agenda (concat "TAGS " match)) (org-prepare-agenda (concat "TAGS " match))
(org-compile-prefix-format 'tags)
(org-set-sorting-strategy 'tags)
(setq org-agenda-query-string match) (setq org-agenda-query-string match)
(setq org-agenda-redo-command (setq org-agenda-redo-command
(list 'org-tags-view (list 'quote todo-only) (list 'org-tags-view (list 'quote todo-only)
@ -4547,6 +4700,8 @@ function from a program - use `org-agenda-get-day-entries' instead."
(when (> (- (org-float-time) (when (> (- (org-float-time)
org-agenda-last-marker-time) org-agenda-last-marker-time)
5) 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-agenda-reset-markers))
(org-compile-prefix-format 'agenda) (org-compile-prefix-format 'agenda)
(org-set-sorting-strategy 'agenda) (org-set-sorting-strategy 'agenda)
@ -4989,9 +5144,9 @@ please use `org-class' instead."
'help-echo 'help-echo
(format "mouse-2 or RET jump to org file %s" (format "mouse-2 or RET jump to org file %s"
(abbreviate-file-name buffer-file-name)))) (abbreviate-file-name buffer-file-name))))
(items (if (consp org-agenda-show-log) (items (if (consp org-agenda-show-log-scoped)
org-agenda-show-log org-agenda-show-log-scoped
(if (eq org-agenda-show-log 'clockcheck) (if (eq org-agenda-show-log-scoped 'clockcheck)
'(clock) '(clock)
org-agenda-log-mode-items))) org-agenda-log-mode-items)))
(parts (parts
@ -5529,151 +5684,163 @@ 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 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. 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." Any match of REMOVE-RE will be removed from TXT."
(save-match-data ;; We keep the org-prefix-* variable values along with a compiled
;; Diary entries sometimes have extra whitespace at the beginning ;; formatter, so that multiple agendas existing at the same time, do
(if (string-match "^ +" txt) (setq txt (replace-match "" nil nil txt))) ;; 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)))
(loop for (var value) in bindings
do (set var value))
(save-match-data
;; Diary entries sometimes have extra whitespace at the beginning
(if (string-match "^ +" txt) (setq txt (replace-match "" nil nil txt)))
;; Fix the tags part in txt ;; Fix the tags part in txt
(setq txt (org-agenda-fix-displayed-tags (setq txt (org-agenda-fix-displayed-tags
txt tags txt tags
org-agenda-show-inherited-tags org-agenda-show-inherited-tags
org-agenda-hide-tags-regexp)) org-agenda-hide-tags-regexp))
(let* ((category (or category (let* ((category (or category
(if (stringp org-category) (if (stringp org-category)
org-category org-category
(and org-category (symbol-name org-category))) (and org-category (symbol-name org-category)))
(if buffer-file-name (if buffer-file-name
(file-name-sans-extension (file-name-sans-extension
(file-name-nondirectory buffer-file-name)) (file-name-nondirectory buffer-file-name))
""))) "")))
(category-icon (org-agenda-get-category-icon category)) (category-icon (org-agenda-get-category-icon category))
(category-icon (if category-icon (category-icon (if category-icon
(propertize " " 'display category-icon) (propertize " " 'display category-icon)
"")) ""))
;; time, tag, effort are needed for the eval of the prefix format ;; time, tag, effort are needed for the eval of the prefix format
(tag (if tags (nth (1- (length tags)) tags) "")) (tag (if tags (nth (1- (length tags)) tags) ""))
time effort neffort time effort neffort
(ts (if dotime (concat (ts (if dotime (concat
(if (stringp dotime) dotime "") (if (stringp dotime) dotime "")
(and org-agenda-search-headline-for-time txt)))) (and org-agenda-search-headline-for-time txt))))
(time-of-day (and dotime (org-get-time-of-day ts))) (time-of-day (and dotime (org-get-time-of-day ts)))
stamp plain s0 s1 s2 rtn srp l stamp plain s0 s1 s2 rtn srp l
duration thecategory) duration thecategory)
(and (eq major-mode 'org-mode) buffer-file-name (and (eq major-mode 'org-mode) buffer-file-name
(add-to-list 'org-agenda-contributing-files buffer-file-name)) (add-to-list 'org-agenda-contributing-files buffer-file-name))
(when (and dotime time-of-day) (when (and dotime time-of-day)
;; Extract starting and ending time and move them to prefix ;; Extract starting and ending time and move them to prefix
(when (or (setq stamp (string-match org-stamp-time-of-day-regexp ts)) (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 plain (string-match org-plain-time-of-day-regexp ts)))
(setq s0 (match-string 0 ts) (setq s0 (match-string 0 ts)
srp (and stamp (match-end 3)) srp (and stamp (match-end 3))
s1 (match-string (if plain 1 2) ts) s1 (match-string (if plain 1 2) ts)
s2 (match-string (if plain 8 (if srp 4 6)) 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 ;; 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. ;; them, we might want to remove them there to avoid duplication.
;; The user can turn this off with a variable. ;; The user can turn this off with a variable.
(if (and org-prefix-has-time (if (and org-prefix-has-time
org-agenda-remove-times-when-in-prefix (or stamp plain) org-agenda-remove-times-when-in-prefix (or stamp plain)
(string-match (concat (regexp-quote s0) " *") txt) (string-match (concat (regexp-quote s0) " *") txt)
(not (equal ?\] (string-to-char (substring txt (match-end 0))))) (not (equal ?\] (string-to-char (substring txt (match-end 0)))))
(if (eq org-agenda-remove-times-when-in-prefix 'beg) (if (eq org-agenda-remove-times-when-in-prefix 'beg)
(= (match-beginning 0) 0) (= (match-beginning 0) 0)
t)) t))
(setq txt (replace-match "" nil nil txt)))) (setq txt (replace-match "" nil nil txt))))
;; Normalize the time(s) to 24 hour ;; Normalize the time(s) to 24 hour
(if s1 (setq s1 (org-get-time-of-day s1 'string t))) (if s1 (setq s1 (org-get-time-of-day s1 'string t)))
(if s2 (setq s2 (org-get-time-of-day s2 'string t))) (if s2 (setq s2 (org-get-time-of-day s2 'string t)))
;; Try to set s2 if s1 and `org-agenda-default-appointment-duration' are set ;; Try to set s2 if s1 and `org-agenda-default-appointment-duration' are set
(when (and s1 (not s2) org-agenda-default-appointment-duration) (when (and s1 (not s2) org-agenda-default-appointment-duration)
(setq s2 (setq s2
(org-minutes-to-hh:mm-string (org-minutes-to-hh:mm-string
(+ (org-hh:mm-string-to-minutes s1) org-agenda-default-appointment-duration)))) (+ (org-hh:mm-string-to-minutes s1) org-agenda-default-appointment-duration))))
;; Compute the duration ;; Compute the duration
(when s2 (when s2
(setq duration (- (org-hh:mm-string-to-minutes s2) (setq duration (- (org-hh:mm-string-to-minutes s2)
(org-hh:mm-string-to-minutes s1))))) (org-hh:mm-string-to-minutes s1)))))
(when (string-match (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") (when (string-match (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$")
txt) txt)
;; Tags are in the string ;; Tags are in the string
(if (or (eq org-agenda-remove-tags t) (if (or (eq org-agenda-remove-tags t)
(and org-agenda-remove-tags (and org-agenda-remove-tags
org-prefix-has-tag)) org-prefix-has-tag))
(setq txt (replace-match "" t t txt)) (setq txt (replace-match "" t t txt))
(setq txt (replace-match (setq txt (replace-match
(concat (make-string (max (- 50 (length txt)) 1) ?\ ) (concat (make-string (max (- 50 (length txt)) 1) ?\ )
(match-string 2 txt)) (match-string 2 txt))
t t txt)))) t t txt))))
(when (eq major-mode 'org-mode) (when (eq major-mode 'org-mode)
(setq effort (setq effort
(condition-case nil (condition-case nil
(org-get-effort (org-get-effort
(or (get-text-property 0 'org-hd-marker txt) (or (get-text-property 0 'org-hd-marker txt)
(get-text-property 0 'org-marker txt))) (get-text-property 0 'org-marker txt)))
(error nil))) (error nil)))
(when effort (when effort
(setq neffort (org-duration-string-to-minutes effort) (setq neffort (org-duration-string-to-minutes effort)
effort (setq effort (concat "[" effort "]"))))) effort (setq effort (concat "[" effort "]")))))
;; prevent erroring out with %e format when there is no effort ;; prevent erroring out with %e format when there is no effort
(or effort (setq effort "")) (or effort (setq effort ""))
(when remove-re (when remove-re
(while (string-match remove-re txt) (while (string-match remove-re txt)
(setq txt (replace-match "" t t txt)))) (setq txt (replace-match "" t t txt))))
;; Set org-heading property on `txt' to mark the start of the ;; Set org-heading property on `txt' to mark the start of the
;; heading. ;; heading.
(add-text-properties 0 (length txt) '(org-heading t) txt) (add-text-properties 0 (length txt) '(org-heading t) txt)
;; Prepare the variables needed in the eval of the compiled format ;; Prepare the variables needed in the eval of the compiled format
(setq time (cond (s2 (concat (setq time (cond (s2 (concat
(org-agenda-time-of-day-to-ampm-maybe s1) (org-agenda-time-of-day-to-ampm-maybe s1)
"-" (org-agenda-time-of-day-to-ampm-maybe s2) "-" (org-agenda-time-of-day-to-ampm-maybe s2)
(if org-agenda-timegrid-use-ampm " "))) (if org-agenda-timegrid-use-ampm " ")))
(s1 (concat (s1 (concat
(org-agenda-time-of-day-to-ampm-maybe s1) (org-agenda-time-of-day-to-ampm-maybe s1)
(if org-agenda-timegrid-use-ampm (if org-agenda-timegrid-use-ampm
"........ " "........ "
"......"))) "......")))
(t "")) (t ""))
extra (or (and (not habitp) extra) "") extra (or (and (not habitp) extra) "")
category (if (symbolp category) (symbol-name category) category) category (if (symbolp category) (symbol-name category) category)
thecategory (copy-sequence category)) thecategory (copy-sequence category))
(if (string-match org-bracket-link-regexp category) (if (string-match org-bracket-link-regexp category)
(progn (progn
(setq l (if (match-end 3) (setq l (if (match-end 3)
(- (match-end 3) (match-beginning 3)) (- (match-end 3) (match-beginning 3))
(- (match-end 1) (match-beginning 1)))) (- (match-end 1) (match-beginning 1))))
(when (< l (or org-prefix-category-length 0)) (when (< l (or org-prefix-category-length 0))
(setq category (copy-sequence category)) (setq category (copy-sequence category))
(org-add-props category nil (org-add-props category nil
'extra-space (make-string 'extra-space (make-string
(- org-prefix-category-length l 1) ?\ )))) (- org-prefix-category-length l 1) ?\ ))))
(if (and org-prefix-category-max-length (if (and org-prefix-category-max-length
(>= (length category) org-prefix-category-max-length)) (>= (length category) org-prefix-category-max-length))
(setq category (substring category 0 (1- org-prefix-category-max-length))))) (setq category (substring category 0 (1- org-prefix-category-max-length)))))
;; Evaluate the compiled format ;; Evaluate the compiled format
(setq rtn (concat (eval org-prefix-format-compiled) txt)) (setq rtn (concat (eval formatter) txt))
;; And finally add the text properties ;; And finally add the text properties
(remove-text-properties 0 (length rtn) '(line-prefix t wrap-prefix t) rtn) (remove-text-properties 0 (length rtn) '(line-prefix t wrap-prefix t) rtn)
(org-add-props rtn nil (org-add-props rtn nil
'org-category (if thecategory (downcase thecategory) category) 'org-category (if thecategory (downcase thecategory) category)
'tags (mapcar 'org-downcase-keep-props tags) 'tags (mapcar 'org-downcase-keep-props tags)
'org-highest-priority org-highest-priority 'org-highest-priority org-highest-priority
'org-lowest-priority org-lowest-priority 'org-lowest-priority org-lowest-priority
'time-of-day time-of-day 'time-of-day time-of-day
'duration duration 'duration duration
'effort effort 'effort effort
'effort-minutes neffort 'effort-minutes neffort
'txt txt 'txt txt
'time time 'time time
'extra extra 'extra extra
'format org-prefix-format-compiled 'format org-prefix-format-compiled
'dotime dotime)))) 'dotime dotime)))))
(defun org-agenda-fix-displayed-tags (txt tags add-inherited hide-re) (defun org-agenda-fix-displayed-tags (txt tags add-inherited hide-re)
"Remove tags string from TXT, and add a modified list of tags. "Remove tags string from TXT, and add a modified list of tags.
@ -5759,8 +5926,8 @@ The modified list may contain inherited tags, and tags matched by
(defun org-compile-prefix-format (key) (defun org-compile-prefix-format (key)
"Compile the prefix format into a Lisp form that can be evaluated. "Compile the prefix format into a Lisp form that can be evaluated.
The resulting form is returned and stored in the variable The resulting form and associated variable bindings is returned
`org-prefix-format-compiled'." and stored in the variable `org-prefix-format-compiled'."
(setq org-prefix-has-time nil org-prefix-has-tag nil (setq org-prefix-has-time nil org-prefix-has-tag nil
org-prefix-category-length nil org-prefix-category-length nil
org-prefix-has-effort nil) org-prefix-has-effort nil)
@ -5804,7 +5971,14 @@ The resulting form is returned and stored in the variable
(setq s (replace-match "%s" t nil s)) (setq s (replace-match "%s" t nil s))
(push varform vars)) (push varform vars))
(setq vars (nreverse vars)) (setq vars (nreverse vars))
(setq org-prefix-format-compiled `(format ,s ,@vars)))) (with-current-buffer org-agenda-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))
`(format ,s ,@vars))))))
(defun org-set-sorting-strategy (key) (defun org-set-sorting-strategy (key)
(if (symbolp (car org-agenda-sorting-strategy)) (if (symbolp (car org-agenda-sorting-strategy))
@ -6139,24 +6313,24 @@ If ERROR is non-nil, throw an error, otherwise just return nil."
(error "Not allowed in %s-type agenda buffers" org-agenda-type) (error "Not allowed in %s-type agenda buffers" org-agenda-type)
nil))) nil)))
(defun org-agenda-quit () (defun org-agenda-Quit (&optional arg)
"Exit agenda by removing the window or the buffer." "Exit agenda by removing the window or the buffer"
(interactive) (interactive)
(if org-agenda-columns-active (if org-agenda-columns-active
(org-columns-quit) (org-columns-quit)
(let ((buf (current-buffer))) (let ((buf (current-buffer)))
(if (eq org-agenda-window-setup 'other-frame) (if (eq org-agenda-window-setup 'other-frame)
(progn (progn
(kill-buffer buf)
(org-agenda-reset-markers) (org-agenda-reset-markers)
(kill-buffer buf)
(org-columns-remove-overlays) (org-columns-remove-overlays)
(setq org-agenda-archives-mode nil) (setq org-agenda-archives-mode nil)
(delete-frame)) (delete-frame))
(and (not (eq org-agenda-window-setup 'current-window)) (and (not (eq org-agenda-window-setup 'current-window))
(not (one-window-p)) (not (one-window-p))
(delete-window)) (delete-window))
(kill-buffer buf)
(org-agenda-reset-markers) (org-agenda-reset-markers)
(kill-buffer buf)
(org-columns-remove-overlays) (org-columns-remove-overlays)
(setq org-agenda-archives-mode nil))) (setq org-agenda-archives-mode nil)))
;; Maybe restore the pre-agenda window configuration. ;; Maybe restore the pre-agenda window configuration.
@ -6165,6 +6339,24 @@ If ERROR is non-nil, throw an error, otherwise just return nil."
org-pre-agenda-window-conf org-pre-agenda-window-conf
(set-window-configuration org-pre-agenda-window-conf)))) (set-window-configuration org-pre-agenda-window-conf))))
(defun org-agenda-quit ()
"Exit agenda by killing agenda buffer or burying it when
`org-agenda-sticky' is non-NIL"
(interactive)
(if org-agenda-columns-active
(org-columns-quit)
(if org-agenda-sticky
(let ((buf (current-buffer)))
(if (eq org-agenda-window-setup 'other-frame)
(progn
(delete-frame))
(and (not (eq org-agenda-window-setup 'current-window))
(not (one-window-p))
(delete-window)))
(with-current-buffer buf
(bury-buffer)))
(org-agenda-Quit))))
(defun org-agenda-exit () (defun org-agenda-exit ()
"Exit agenda by removing the window or the buffer. "Exit agenda by removing the window or the buffer.
Also kill all Org-mode buffers which have been loaded by `org-agenda'. Also kill all Org-mode buffers which have been loaded by `org-agenda'.
@ -6172,7 +6364,18 @@ Org-mode buffers visited directly by the user will not be touched."
(interactive) (interactive)
(org-release-buffers org-agenda-new-buffers) (org-release-buffers org-agenda-new-buffers)
(setq org-agenda-new-buffers nil) (setq org-agenda-new-buffers nil)
(org-agenda-quit)) (org-agenda-Quit))
(defun org-agenda-kill-all-agenda-buffers ()
"Kill all buffers in `org-agena-mode'.
This is used when toggling sticky agendas. You can also explicitly invoke it
with `C-c a C-k'."
(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) (defun org-agenda-execute (arg)
"Execute another agenda command, keeping same window. "Execute another agenda command, keeping same window.
@ -6186,7 +6389,11 @@ in the agenda."
"Rebuild Agenda. "Rebuild Agenda.
When this is the global TODO list, a prefix argument will be interpreted." When this is the global TODO list, a prefix argument will be interpreted."
(interactive) (interactive)
(let* ((org-agenda-keep-modes t) (let* ((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-filter org-agenda-tag-filter)
(tag-preset (get 'org-agenda-tag-filter :preset-filter)) (tag-preset (get 'org-agenda-tag-filter :preset-filter))
(cat-filter org-agenda-category-filter) (cat-filter org-agenda-category-filter)
@ -6302,7 +6509,7 @@ to switch to narrowing."
(message "Effort%s: %s " effort-op effort-prompt) (message "Effort%s: %s " effort-op effort-prompt)
(setq char (read-char-exclusive)) (setq char (read-char-exclusive))
(when (or (< char ?0) (> char ?9)) (when (or (< char ?0) (> char ?9))
(error "Need 1-9,0 to select effort" )))) (error "Need 1-9,0 to select effort"))))
(when (equal char ?\t) (when (equal char ?\t)
(unless (local-variable-p 'org-global-tags-completion-table (current-buffer)) (unless (local-variable-p 'org-global-tags-completion-table (current-buffer))
(org-set-local 'org-global-tags-completion-table (org-set-local 'org-global-tags-completion-table
@ -7473,6 +7680,7 @@ 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." If FORCE-TAGS is non nil, the car of it returns the new tags."
(let* ((inhibit-read-only t) (let* ((inhibit-read-only t)
(line (org-current-line)) (line (org-current-line))
(org-agenda-buffer (current-buffer))
(thetags (with-current-buffer (marker-buffer hdmarker) (thetags (with-current-buffer (marker-buffer hdmarker)
(save-excursion (save-restriction (widen) (save-excursion (save-restriction (widen)
(goto-char hdmarker) (goto-char hdmarker)
@ -7493,13 +7701,13 @@ If FORCE-TAGS is non nil, the car of it returns the new tags."
new new
(let ((org-prefix-format-compiled (let ((org-prefix-format-compiled
(or (get-text-property (point) 'format) (or (get-text-property (point) 'format)
org-prefix-format-compiled))) org-prefix-format-compiled))
(extra (org-get-at-bol 'extra)))
(with-current-buffer (marker-buffer hdmarker) (with-current-buffer (marker-buffer hdmarker)
(save-excursion (save-excursion
(save-restriction (save-restriction
(widen) (widen)
(org-agenda-format-item (org-get-at-bol 'extra) (org-agenda-format-item extra newhead cat tags dotime)))))
newhead cat tags dotime)))))
pl (text-property-any (point-at-bol) (point-at-eol) 'org-heading t) pl (text-property-any (point-at-bol) (point-at-eol) 'org-heading t)
undone-face (org-get-at-bol 'undone-face) undone-face (org-get-at-bol 'undone-face)
done-face (org-get-at-bol 'done-face)) done-face (org-get-at-bol 'done-face))