aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarsten Dominik2005-05-20 11:24:48 +0000
committerCarsten Dominik2005-05-20 11:24:48 +0000
commiteb2f9c591be5562ff3c1d5f21d22d3c7b5ef538e (patch)
tree360ca2d5d44403686268660aef6fc4c356a37311
parentf3fbdb1f2d2659ca7bd36d9df425cde539dfccdf (diff)
downloademacs-eb2f9c591be5562ff3c1d5f21d22d3c7b5ef538e.tar.gz
emacs-eb2f9c591be5562ff3c1d5f21d22d3c7b5ef538e.zip
(org-agenda-toggle-time-grid): New command.
(org-agenda-use-time-grid, org-agenda-time-grid): New options. (org-agenda-add-time-grid-maybe): New function. (org-agenda): Call `org-agenda-add-time-grid-maybe'. (org-table-create): `dotimes' instead of `mapcar'. (org-xor): Simplified implementation. (org-agenda): `inhibit-redisplay' turned on. (org-agenda-change-all-lines): Use `org-format-agenda-item' to get a consistent line after a state change. (org-agenda-remove-times-when-in-prefix): New option. (org-prefix-has-time): New variable. (org-parse-time-string): Optional argument NODEFAULT. (org-format-agenda-item): Parse items for time-of-day specifications and move these into the prefix if possible. (org-agenda-priority): Get current heading, not previous heading during agenda remote editing.
-rw-r--r--lisp/textmodes/org.el539
1 files changed, 392 insertions, 147 deletions
diff --git a/lisp/textmodes/org.el b/lisp/textmodes/org.el
index 1b3585d56a9..bd81f97138c 100644
--- a/lisp/textmodes/org.el
+++ b/lisp/textmodes/org.el
@@ -5,7 +5,7 @@
5;; Author: Carsten Dominik <dominik at science dot uva dot nl> 5;; Author: Carsten Dominik <dominik at science dot uva dot nl>
6;; Keywords: outlines, hypermedia, calendar 6;; Keywords: outlines, hypermedia, calendar
7;; Homepage: http://www.astro.uva.nl/~dominik/Tools/org/ 7;; Homepage: http://www.astro.uva.nl/~dominik/Tools/org/
8;; Version: 3.08 8;; Version: 3.09
9;; 9;;
10;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
11;; 11;;
@@ -31,27 +31,30 @@
31;; project planning with a fast and effective plain-text system. 31;; project planning with a fast and effective plain-text system.
32;; 32;;
33;; Org-mode develops organizational tasks around a NOTES file that contains 33;; Org-mode develops organizational tasks around a NOTES file that contains
34;; information about projects as plain text. Org-mode is implemented on 34;; information about projects as plain text. Org-mode is implemented on top
35;; top of outline-mode - ideal to keep the content of large files well 35;; of outline-mode - ideal to keep the content of large files well structured.
36;; structured. It supports ToDo items, deadlines and time stamps, which 36;; It supports ToDo items, deadlines and time stamps, which can be extracted
37;; magically appear in the diary listing of the Emacs calendar. Tables are 37;; to create a daily/weekly agenda that also integrates the diary of the Emacs
38;; easily created with a built-in table editor. Plain text URL-like links 38;; calendar. Tables are easily created with a built-in table editor. Plain
39;; connect to websites, emails (VM,RMAIL,WANDERLUST), Usenet messages (Gnus), 39;; text URL-like links connect to websites, emails (VM, RMAIL, WANDERLUST),
40;; BBDB entries, and any files related to the projects. For printing and 40;; Usenet messages (Gnus), BBDB entries, and any files related to the
41;; sharing of notes, an Org-mode file (or a part of it) can be exported as 41;; projects. For printing and sharing of notes, an Org-mode file (or a part
42;; a structured ASCII file, or as HTML. 42;; of it) can be exported as a structured ASCII file, or as HTML.
43;; 43;;
44;; Installation 44;; Installation
45;; ------------ 45;; ------------
46;; The instruction below assume that you have downloaded Org-mode from the 46;; If Org-mode is part of the Emacs distribution or an XEmacs package, you
47;; web. If Org-mode is part of the Emacs distribution or an XEmacs package, 47;; only need to copy the following lines to your .emacs file. The last two
48;; you only need to add to .emacs the last three lines of Lisp code listed 48;; lines define *global* keys for the commands `org-store-link' and
49;; below, i.e. the `auto-mode-alist' modification and the global key bindings. 49;; `org-agenda' - please choose suitable keys yourself.
50;; 50;;
51;; Byte-compile org.el and put it on your load path. Then copy the 51;; (add-to-list 'auto-mode-alist '("\\.org$" . org-mode))
52;; following lines into .emacs. The last two lines define *global* 52;; (define-key global-map "\C-cl" 'org-store-link)
53;; keys for the commands `org-store-link' and `org-agenda' - please 53;; (define-key global-map "\C-ca" 'org-agenda)
54;; choose suitable keys yourself. 54;;
55;; If you have downloaded Org-mode from the Web, you must byte-compile
56;; org.el and put it on your load path. In addition to the Emacs Lisp
57;; lines above, you also need to add the following lines to .emacs:
55;; 58;;
56;; (autoload 'org-mode "org" "Org mode" t) 59;; (autoload 'org-mode "org" "Org mode" t)
57;; (autoload 'org-diary "org" "Diary entries from Org mode") 60;; (autoload 'org-diary "org" "Diary entries from Org mode")
@@ -59,12 +62,9 @@
59;; (autoload 'org-store-link "org" "Store a link to the current location" t) 62;; (autoload 'org-store-link "org" "Store a link to the current location" t)
60;; (autoload 'orgtbl-mode "org" "Org tables as a minor mode" t) 63;; (autoload 'orgtbl-mode "org" "Org tables as a minor mode" t)
61;; (autoload 'turn-on-orgtbl "org" "Org tables as a minor mode") 64;; (autoload 'turn-on-orgtbl "org" "Org tables as a minor mode")
62;; (add-to-list 'auto-mode-alist '("\\.org$" . org-mode))
63;; (define-key global-map "\C-cl" 'org-store-link)
64;; (define-key global-map "\C-ca" 'org-agenda)
65;; 65;;
66;; This will put all files with extension ".org" into Org-mode. As an 66;; This setup will put all files with extension ".org" into Org-mode. As
67;; alternative, make the first line of a file look like this: 67;; an alternative, make the first line of a file look like this:
68;; 68;;
69;; MY PROJECTS -*- mode: org; -*- 69;; MY PROJECTS -*- mode: org; -*-
70;; 70;;
@@ -73,12 +73,18 @@
73;; 73;;
74;; Documentation 74;; Documentation
75;; ------------- 75;; -------------
76;; The documentation of Org-mode can be found in the TeXInfo file. 76;; The documentation of Org-mode can be found in the TeXInfo file. The
77;; The distribution also contains a PDF version of it. At the homepage 77;; distribution also contains a PDF version of it. At the homepage of
78;; of Org-mode, you can read the same text online as HTML. 78;; Org-mode, you can read the same text online as HTML. There is also an
79;; excellent reference card made by Philip Rooke.
79;; 80;;
80;; Changes: 81;; Changes:
81;; ------- 82;; -------
83;; Version 3.09
84;; - Time-of-day specifications in agenda are extracted and placed
85;; into the prefix. Timed entries can be placed into a time grid for
86;; day.
87;;
82;; Version 3.08 88;; Version 3.08
83;; - "|" no longer allowed as part of a link, to allow links in tables. 89;; - "|" no longer allowed as part of a link, to allow links in tables.
84;; - The prefix of items in the agenda buffer can be configured. 90;; - The prefix of items in the agenda buffer can be configured.
@@ -136,7 +142,7 @@
136;; warnings about upcoming deadlines/overdue scheduled items. 142;; warnings about upcoming deadlines/overdue scheduled items.
137;; That functionality is now limited to the (multifile) agenda. 143;; That functionality is now limited to the (multifile) agenda.
138;; - When reading a date, the calendar can be manipulated with keys. 144;; - When reading a date, the calendar can be manipulated with keys.
139;; - Link support for RMAIL and Wanderlust (from planner.el, untested) 145;; - Link support for RMAIL and Wanderlust (from planner.el, untested).
140;; - Minor bug fixes and documentation improvements. 146;; - Minor bug fixes and documentation improvements.
141 147
142;;; Code: 148;;; Code:
@@ -148,16 +154,15 @@
148 154
149;;; Customization variables 155;;; Customization variables
150 156
151(defvar org-version "3.08" 157(defvar org-version "3.09"
152 "The version number of the file org.el.") 158 "The version number of the file org.el.")
153(defun org-version () 159(defun org-version ()
154 (interactive) 160 (interactive)
155 (message "Org-mode version %s" org-version)) 161 (message "Org-mode version %s" org-version))
156 162
157;; The following two constants are for compatibility with different 163;; The following two constants are for compatibility with different Emacs
158;; Emacs versions (Emacs versus XEmacs) and with different versions of 164;; versions (Emacs versus XEmacs) and with different versions of outline.el.
159;; outline.el. All the compatibility code in org.el is based on these two 165;; The compatibility code in org.el is based on these two constants.
160;; constants.
161(defconst org-xemacs-p (featurep 'xemacs) 166(defconst org-xemacs-p (featurep 'xemacs)
162 "Are we running xemacs?") 167 "Are we running xemacs?")
163(defconst org-noutline-p (featurep 'noutline) 168(defconst org-noutline-p (featurep 'noutline)
@@ -570,7 +575,7 @@ the grouped in categories, don't sort the categories, but keep them in
570the sequence given in `org-agenda-files'. Within each category sort by 575the sequence given in `org-agenda-files'. Within each category sort by
571priority. 576priority.
572 577
573Leaving out the `category-keep' would mean that items will be sorted across 578Leaving out `category-keep' would mean that items will be sorted across
574categories by priority." 579categories by priority."
575 :group 'org-agenda 580 :group 'org-agenda
576 :type '(repeat 581 :type '(repeat
@@ -583,7 +588,7 @@ categories by priority."
583 (const priority-up) 588 (const priority-up)
584 (const priority-down)))) 589 (const priority-down))))
585 590
586(defcustom org-agenda-prefix-format " %-12:c% s" 591(defcustom org-agenda-prefix-format " %-12:c%?-12t% s"
587 "Format specification for the prefix of items in the agenda buffer. 592 "Format specification for the prefix of items in the agenda buffer.
588This format works similar to a printf format, with the following meaning: 593This format works similar to a printf format, with the following meaning:
589 594
@@ -593,22 +598,39 @@ This format works similar to a printf format, with the following meaning:
593 format HH:MM 598 format HH:MM
594 %s Scheduling/Deadline information, a short string 599 %s Scheduling/Deadline information, a short string
595 600
596In addition to the normal printf field modifiers like field width and 601All specifiers work basically like the standard `%s' of printf, but may
597padding instructions, in this format you can also add an additional 602contain two additional characters: A question mark just after the `%' and
598punctuation or whitespace character just before the final format letter. 603a whitespace/punctuation character just before the final letter.
599This character will be appended to the field value if the value is not 604
600empty. For example, the format \"%-12:c\" leads to \"Diary: \" if 605If the first character after `%' is a question mark, the entire field
601the category is \"Diary\". If the category were be empty, no additional 606will only be included if the corresponding value applies to the
602colon would be interted. 607current entry. This is useful for fields which should have fixed
603 608width when present, but zero width when absent. For example,
604Including `%t' in the format string leads to a double time specification 609\"%?-12t\" will result in a 12 character time field if a time of the
605because the headline/diary item will contain the time specification as 610day is specified, but will completely disappear in entries which do
606well. However, using `%t' in the format will result in a canonical 24 611not contain a time.
607hour time specification at a consistent position in the prefix, while the 612
608time specification in the headline/diary item may be at any position and in 613If there is punctuation or whitespace character just before the final
609various formats. 614format letter, this character will be appended to the field value if
610Example: 615the value is not empty. For example, the format \"%-12:c\" leads to
611 (setq org-agenda-prefix-format \" %-12:c% t% s\")" 616\"Diary: \" if the category is \"Diary\". If the category were be
617empty, no additional colon would be interted.
618
619The default value of this option is \" %-12:c%?-12t% s\", meaning:
620- Indent the line with two space characters
621- Give the category in a 12 chars wide field, padded with whitespace on
622 the right (because of `-'). Append a colon if there is a category
623 (because of `:').
624- If there is a time-of-day, put it into a 12 chars wide field. If no
625 time, don't put in an empty field, just skip it (because of '?').
626- Finally, put the scheduling information and append a whitespace.
627
628As another example, if you don't want the time-of-day of entries in
629the prefix, you could use:
630
631 (setq org-agenda-prefix-format \" %-11:c% s\")
632
633See also the variable `org-agenda-remove-times-when-in-prefix'."
612 :type 'string 634 :type 'string
613 :group 'org-agenda) 635 :group 'org-agenda)
614 636
@@ -618,13 +640,64 @@ Example:
618 :group 'org-agenda) 640 :group 'org-agenda)
619 641
620(defvar org-prefix-format-compiled nil 642(defvar org-prefix-format-compiled nil
621 "The compiled version of `org-???-prefix-format'.") 643 "The compiled version of the most recently used prefix format.
644Depending on which command was used last, this may be the compiled version
645of `org-agenda-prefix-format' or `org-timeline-prefix-format'.")
646
647(defcustom org-agenda-use-time-grid t
648 "Non-nil means, show a time grid in the agenda schedule.
649A time grid is a set of lines for specific times (like every two hours between
6508:00 and 20:00. The items scheduled for a day at specific times are
651sorted in between these lines.
652For deails about when the grid will be shown, and what it will look like, see
653the variable `org-agenda-time-grid'."
654 :group 'org-agenda
655 :type 'boolean)
656
657(defcustom org-agenda-time-grid
658 '((daily today require-timed)
659 "----------------"
660 (800 1000 1200 1400 1600 1800 2000))
661
662 "FIXME: document"
663 :group 'org-agenda
664 :type
665 '(list
666 (set :greedy t :tag "Grid Display Options"
667 (const :tag "Show grid in single day agenda display" daily)
668 (const :tag "Show grid in weekly agenda display" weekly)
669 (const :tag "Always show grid for today" today)
670 (const :tag "Show grid only if any timed entries are present"
671 require-timed)
672 (const :tag "Skip grid times already present in an entry"
673 remove-match))
674 (string :tag "Grid String")
675 (repeat :tag "Grid Times" (integer :tag "Time"))))
676
677(defcustom org-agenda-remove-times-when-in-prefix t
678 "Non-nil means, remove duplicate time specifications in agenda items.
679When the format `org-agenda-prefix-format' contains a `%t' specifier, a
680time-of-day specification in a headline or diary entry is extracted and
681placed into the prefix. If this option is non-nil, the original specification
682\(a timestamp or -range, or just a plain time(range) specification like
68311:30-4pm) will be removed for agenda display. This makes the agenda less
684cluttered.
685The option can be t or nil. It may also be the symbol `beg', indicating
686that the time should only be removed what it is located at the beginning of
687the headline/diary entry."
688 :group 'org-agenda
689 :type '(choice
690 (const :tag "Always" t)
691 (const :tag "Never" nil)
692 (const :tag "When at beginning of entry" beg)))
622 693
623(defcustom org-sort-agenda-notime-is-late t 694(defcustom org-sort-agenda-notime-is-late t
624 "Non-nil means, items without time are considered late. 695 "Non-nil means, items without time are considered late.
625This is only relevant for sorting. When t, items which have no explicit 696This is only relevant for sorting. When t, items which have no explicit
626time like 15:30 will be considered as 24:01, i.e. later than any items which 697time like 15:30 will be considered as 24:01, i.e. later than any items which
627do have a time. When nil, the default time is before 0:00." 698do have a time. When nil, the default time is before 0:00. You can use this
699option to decide if the schedule for today should come before or after timeless
700agenda entries."
628 :group 'org-agenda 701 :group 'org-agenda
629 :type 'boolean) 702 :type 'boolean)
630 703
@@ -1370,6 +1443,14 @@ When this is non-nil, the headline after the keyword is set to the
1370 "Face used for tables." 1443 "Face used for tables."
1371 :group 'org-faces) 1444 :group 'org-faces)
1372 1445
1446(defface org-time-grid-face ;; font-lock-variable-name-face
1447 '((((type tty) (class color)) (:foreground "yellow" :weight light))
1448 (((class color) (background light)) (:foreground "DarkGoldenrod"))
1449 (((class color) (background dark)) (:foreground "LightGoldenrod"))
1450 (t (:bold t :italic t)))
1451 "Face used for level 2 headlines."
1452 :group 'org-faces)
1453
1373(defvar org-level-faces 1454(defvar org-level-faces
1374 '( 1455 '(
1375 org-level-1-face 1456 org-level-1-face
@@ -1496,7 +1577,7 @@ The following commands are available:
1496 (save-excursion 1577 (save-excursion
1497 (goto-char (point-min)) 1578 (goto-char (point-min))
1498 (insert " -*- mode: org -*-\n\n"))) 1579 (insert " -*- mode: org -*-\n\n")))
1499 (run-hooks 'org-mode-hook) ;FIXME: Should be run-mode-hooks. 1580 (run-hooks 'org-mode-hook)
1500 (unless org-inhibit-startup 1581 (unless org-inhibit-startup
1501 (if org-startup-with-deadline-check 1582 (if org-startup-with-deadline-check
1502 (call-interactively 'org-check-deadlines) 1583 (call-interactively 'org-check-deadlines)
@@ -1565,7 +1646,7 @@ The following commands are available:
1565 (save-excursion 1646 (save-excursion
1566 (org-back-to-heading t) 1647 (org-back-to-heading t)
1567 (- (match-end 0) (match-beginning 0)))) 1648 (- (match-end 0) (match-beginning 0))))
1568 1649
1569(defvar org-font-lock-keywords nil) 1650(defvar org-font-lock-keywords nil)
1570 1651
1571(defun org-set-font-lock-defaults () 1652(defun org-set-font-lock-defaults ()
@@ -2844,13 +2925,17 @@ days in order to avoid rounding problems."
2844(defun org-time-string-to-time (s) 2925(defun org-time-string-to-time (s)
2845 (apply 'encode-time (org-parse-time-string s))) 2926 (apply 'encode-time (org-parse-time-string s)))
2846 2927
2847(defun org-parse-time-string (s) 2928(defun org-parse-time-string (s &optional nodefault)
2848 "Parse the standard Org-mode time string. 2929 "Parse the standard Org-mode time string.
2849This should be a lot faster than the normal `parse-time-string'." 2930This should be a lot faster than the normal `parse-time-string'.
2931If time is not given, defaults to 0:00. However, with optional NODEFAULT,
2932hour and minute fields will be nil if not given."
2850 (if (string-match org-ts-regexp1 s) 2933 (if (string-match org-ts-regexp1 s)
2851 (list 0 2934 (list 0
2852 (string-to-number (or (match-string 8 s) "0")) 2935 (if (or (match-beginning 8) (not nodefault))
2853 (string-to-number (or (match-string 7 s) "0")) 2936 (string-to-number (or (match-string 8 s) "0")))
2937 (if (or (match-beginning 7) (not nodefault))
2938 (string-to-number (or (match-string 7 s) "0")))
2854 (string-to-number (match-string 4 s)) 2939 (string-to-number (match-string 4 s))
2855 (string-to-number (match-string 3 s)) 2940 (string-to-number (match-string 3 s))
2856 (string-to-number (match-string 2 s)) 2941 (string-to-number (match-string 2 s))
@@ -3056,6 +3141,7 @@ The following commands are available:
3056 3141
3057(define-key org-agenda-mode-map "f" 'org-agenda-follow-mode) 3142(define-key org-agenda-mode-map "f" 'org-agenda-follow-mode)
3058(define-key org-agenda-mode-map "d" 'org-agenda-toggle-diary) 3143(define-key org-agenda-mode-map "d" 'org-agenda-toggle-diary)
3144(define-key org-agenda-mode-map "g" 'org-agenda-toggle-time-grid)
3059(define-key org-agenda-mode-map "r" 'org-agenda-redo) 3145(define-key org-agenda-mode-map "r" 'org-agenda-redo)
3060(define-key org-agenda-mode-map "q" 'org-agenda-quit) 3146(define-key org-agenda-mode-map "q" 'org-agenda-quit)
3061(define-key org-agenda-mode-map "x" 'org-agenda-exit) 3147(define-key org-agenda-mode-map "x" 'org-agenda-exit)
@@ -3115,7 +3201,7 @@ The following commands are available:
3115 ["Decrease Priority" org-agenda-priority-down t] 3201 ["Decrease Priority" org-agenda-priority-down t]
3116 ["Show Priority" org-agenda-show-priority t]) 3202 ["Show Priority" org-agenda-show-priority t])
3117 "--" 3203 "--"
3118 ["Rebuild" org-agenda-redo t] 3204 ["Rebuild buffer" org-agenda-redo t]
3119 ["Goto Today" org-agenda-goto-today t] 3205 ["Goto Today" org-agenda-goto-today t]
3120 ["Next Dates" org-agenda-later (local-variable-p 'starting-day)] 3206 ["Next Dates" org-agenda-later (local-variable-p 'starting-day)]
3121 ["Previous Dates" org-agenda-earlier (local-variable-p 'starting-day)] 3207 ["Previous Dates" org-agenda-earlier (local-variable-p 'starting-day)]
@@ -3124,6 +3210,8 @@ The following commands are available:
3124 (local-variable-p 'starting-day)] 3210 (local-variable-p 'starting-day)]
3125 ["Include Diary" org-agenda-toggle-diary 3211 ["Include Diary" org-agenda-toggle-diary
3126 :style toggle :selected org-agenda-include-diary :active t] 3212 :style toggle :selected org-agenda-include-diary :active t]
3213 ["Use Time Grid" org-agenda-toggle-time-grid
3214 :style toggle :selected org-agenda-use-time-grid :active t]
3127 "--" 3215 "--"
3128 ["New Diary Entry" org-agenda-diary-entry t] 3216 ["New Diary Entry" org-agenda-diary-entry t]
3129 ("Calendar Commands" 3217 ("Calendar Commands"
@@ -3294,11 +3382,13 @@ NDAYS defaults to `org-agenda-ndays'."
3294 (d (- nt n1))) 3382 (d (- nt n1)))
3295 (- sd (+ (if (< d 0) 7 0) d))))) 3383 (- sd (+ (if (< d 0) 7 0) d)))))
3296 (day-numbers (list start)) 3384 (day-numbers (list start))
3297 s e rtn rtnall file date d start-pos end-pos) 3385 (inhibit-redisplay t)
3386 s e rtn rtnall file date d start-pos end-pos todayp nd)
3298 (setq org-agenda-redo-command 3387 (setq org-agenda-redo-command
3299 (list 'org-agenda include-all start-day ndays)) 3388 (list 'org-agenda include-all start-day ndays))
3300 ;; Make the list of days 3389 ;; Make the list of days
3301 (setq ndays (or ndays org-agenda-ndays)) 3390 (setq ndays (or ndays org-agenda-ndays)
3391 nd ndays)
3302 (while (> ndays 1) 3392 (while (> ndays 1)
3303 (push (1+ (car day-numbers)) day-numbers) 3393 (push (1+ (car day-numbers)) day-numbers)
3304 (setq ndays (1- ndays))) 3394 (setq ndays (1- ndays)))
@@ -3324,11 +3414,15 @@ NDAYS defaults to `org-agenda-ndays'."
3324 rtn (org-agenda-get-day-entries 3414 rtn (org-agenda-get-day-entries
3325 file date :todo)) 3415 file date :todo))
3326 (setq rtnall (append rtnall rtn)))) 3416 (setq rtnall (append rtnall rtn))))
3327 (if rtnall (insert (org-finalize-agenda-entries rtnall) "\n"))) 3417 (when rtnall
3418 (insert "ALL CURRENTLY OPEN TODO ITEMS:\n")
3419 (add-text-properties (point-min) (1- (point))
3420 (list 'face 'org-link-face))
3421 (insert (org-finalize-agenda-entries rtnall) "\n")))
3328 (while (setq d (pop day-numbers)) 3422 (while (setq d (pop day-numbers))
3329 (setq date (calendar-gregorian-from-absolute d) 3423 (setq date (calendar-gregorian-from-absolute d)
3330 s (point)) 3424 s (point))
3331 (if (or (= d today) 3425 (if (or (setq todayp (= d today))
3332 (and (not start-pos) (= d sd))) 3426 (and (not start-pos) (= d sd)))
3333 (setq start-pos (point)) 3427 (setq start-pos (point))
3334 (if (and start-pos (not end-pos)) 3428 (if (and start-pos (not end-pos))
@@ -3347,14 +3441,18 @@ NDAYS defaults to `org-agenda-ndays'."
3347 (setq rtnall (append rtnall rtn)))) 3441 (setq rtnall (append rtnall rtn))))
3348 (if (or rtnall org-agenda-show-all-dates) 3442 (if (or rtnall org-agenda-show-all-dates)
3349 (progn 3443 (progn
3350 (insert (format "%-9s %2d %-9s %4d\n" 3444 (insert (format "%-9s %2d %s %4d\n"
3351 (calendar-day-name date) 3445 (calendar-day-name date)
3352 (extract-calendar-day date) 3446 (extract-calendar-day date)
3353 (calendar-month-name (extract-calendar-month date)) 3447 (calendar-month-name (extract-calendar-month date))
3354 (extract-calendar-year date))) 3448 (extract-calendar-year date)))
3355 (put-text-property s (1- (point)) 'face 3449 (put-text-property s (1- (point)) 'face
3356 'org-link-face) 3450 'org-link-face)
3357 (if rtnall (insert (org-finalize-agenda-entries rtnall) "\n")) 3451 (if rtnall (insert
3452 (org-finalize-agenda-entries ;; FIXME: condition needed
3453 (org-agenda-add-time-grid-maybe
3454 rtnall nd todayp))
3455 "\n"))
3358 (put-text-property s (1- (point)) 'day d)))) 3456 (put-text-property s (1- (point)) 'day d))))
3359 (goto-char (point-min)) 3457 (goto-char (point-min))
3360 (setq buffer-read-only t) 3458 (setq buffer-read-only t)
@@ -3502,6 +3600,15 @@ With prefix ARG, go back that many times `org-agenda-ndays'."
3502 (message "Diary inclusion turned %s" 3600 (message "Diary inclusion turned %s"
3503 (if org-agenda-include-diary "on" "off"))) 3601 (if org-agenda-include-diary "on" "off")))
3504 3602
3603(defun org-agenda-toggle-time-grid ()
3604 "Toggle follow mode in an agenda buffer."
3605 (interactive)
3606 (setq org-agenda-use-time-grid (not org-agenda-use-time-grid))
3607 (org-agenda-redo)
3608 (org-agenda-set-mode-name)
3609 (message "Time-grid turned %s"
3610 (if org-agenda-use-time-grid "on" "off")))
3611
3505(defun org-agenda-set-mode-name () 3612(defun org-agenda-set-mode-name ()
3506 "Set the mode name to indicate all the small mode settings." 3613 "Set the mode name to indicate all the small mode settings."
3507 (setq mode-name 3614 (setq mode-name
@@ -3509,7 +3616,8 @@ With prefix ARG, go back that many times `org-agenda-ndays'."
3509 (if (equal org-agenda-ndays 1) " Day" "") 3616 (if (equal org-agenda-ndays 1) " Day" "")
3510 (if (equal org-agenda-ndays 7) " Week" "") 3617 (if (equal org-agenda-ndays 7) " Week" "")
3511 (if org-agenda-follow-mode " Follow" "") 3618 (if org-agenda-follow-mode " Follow" "")
3512 (if org-agenda-include-diary " Diary" ""))) 3619 (if org-agenda-include-diary " Diary" "")
3620 (if org-agenda-use-time-grid " Grid" "")))
3513 (force-mode-line-update)) 3621 (force-mode-line-update))
3514 3622
3515(defun org-agenda-post-command-hook () 3623(defun org-agenda-post-command-hook ()
@@ -3524,7 +3632,7 @@ With prefix ARG, go back that many times `org-agenda-ndays'."
3524 "Get the (Emacs Calendar) diary entries for DATE." 3632 "Get the (Emacs Calendar) diary entries for DATE."
3525 (let* ((fancy-diary-buffer "*temporary-fancy-diary-buffer*") 3633 (let* ((fancy-diary-buffer "*temporary-fancy-diary-buffer*")
3526 (diary-display-hook '(fancy-diary-display)) 3634 (diary-display-hook '(fancy-diary-display))
3527 (list-diary-entries-hook 3635 (list-diary-entries-hook
3528 (cons 'org-diary-default-entry list-diary-entries-hook)) 3636 (cons 'org-diary-default-entry list-diary-entries-hook))
3529 entries 3637 entries
3530 (org-disable-diary t)) 3638 (org-disable-diary t))
@@ -3551,7 +3659,7 @@ With prefix ARG, go back that many times `org-agenda-ndays'."
3551 (setq entries 3659 (setq entries
3552 (mapcar 3660 (mapcar
3553 (lambda (x) 3661 (lambda (x)
3554 (setq x (org-format-agenda-item "" x "Diary")) 3662 (setq x (org-format-agenda-item "" x "Diary" 'time))
3555 ;; Extend the text properties to the beginning of the line 3663 ;; Extend the text properties to the beginning of the line
3556 (add-text-properties 3664 (add-text-properties
3557 0 (length x) 3665 0 (length x)
@@ -3764,7 +3872,7 @@ the documentation of `org-diary'."
3764 arg results rtn) 3872 arg results rtn)
3765 (if (not buffer) 3873 (if (not buffer)
3766 ;; If file does not exist, make sure an error message ends up in diary 3874 ;; If file does not exist, make sure an error message ends up in diary
3767 (format "ORG-AGENDA-ERROR: No such org-file %s" file) 3875 (list (format "ORG-AGENDA-ERROR: No such org-file %s" file))
3768 (with-current-buffer buffer 3876 (with-current-buffer buffer
3769 (unless (eq major-mode 'org-mode) 3877 (unless (eq major-mode 'org-mode)
3770 (error "Agenda file %s is not in `org-mode'" file)) 3878 (error "Agenda file %s is not in `org-mode'" file))
@@ -3796,8 +3904,8 @@ the documentation of `org-diary'."
3796 ((and (eq arg :deadline) 3904 ((and (eq arg :deadline)
3797 (equal date (calendar-current-date))) 3905 (equal date (calendar-current-date)))
3798 (setq rtn (org-agenda-get-deadlines)) 3906 (setq rtn (org-agenda-get-deadlines))
3799 (setq results (append results rtn)))))))))) 3907 (setq results (append results rtn))))))))
3800 results)) 3908 results))))
3801 3909
3802(defun org-entry-is-done-p () 3910(defun org-entry-is-done-p ()
3803 "Is the current entry marked DONE?" 3911 "Is the current entry marked DONE?"
@@ -3876,7 +3984,7 @@ the documentation of `org-diary'."
3876 (list 0 0 0 (nth 1 date) (car date) (nth 2 date)))) 3984 (list 0 0 0 (nth 1 date) (car date) (nth 2 date))))
3877 0 11))) 3985 0 11)))
3878 marker hdmarker deadlinep scheduledp donep tmp priority 3986 marker hdmarker deadlinep scheduledp donep tmp priority
3879 ee txt) 3987 ee txt timestr)
3880 (goto-char (point-min)) 3988 (goto-char (point-min))
3881 (while (re-search-forward regexp nil t) 3989 (while (re-search-forward regexp nil t)
3882 (if (not (save-match-data (org-at-date-range-p))) 3990 (if (not (save-match-data (org-at-date-range-p)))
@@ -3886,9 +3994,13 @@ the documentation of `org-diary'."
3886 (- (match-beginning 0) 3994 (- (match-beginning 0)
3887 org-ds-keyword-length)) 3995 org-ds-keyword-length))
3888 (match-beginning 0)) 3996 (match-beginning 0))
3997 timestr (buffer-substring (match-beginning 0) (point-at-eol))
3889 deadlinep (string-match org-deadline-regexp tmp) 3998 deadlinep (string-match org-deadline-regexp tmp)
3890 scheduledp (string-match org-scheduled-regexp tmp) 3999 scheduledp (string-match org-scheduled-regexp tmp)
3891 donep (org-entry-is-done-p)) 4000 donep (org-entry-is-done-p))
4001 (if (string-match ">" timestr)
4002 ;; substring should only run to end of time stamp
4003 (setq timestr (substring timestr 0 (match-end 0))))
3892 (save-excursion 4004 (save-excursion
3893 (if (re-search-backward "\\(^\\|\r\\)\\*+" nil t) 4005 (if (re-search-backward "\\(^\\|\r\\)\\*+" nil t)
3894 (progn 4006 (progn
@@ -3899,7 +4011,7 @@ the documentation of `org-diary'."
3899 (format "%s%s" 4011 (format "%s%s"
3900 (if deadlinep "Deadline: " "") 4012 (if deadlinep "Deadline: " "")
3901 (if scheduledp "Scheduled: " "")) 4013 (if scheduledp "Scheduled: " ""))
3902 (match-string 1)))) 4014 (match-string 1) nil timestr)))
3903 (setq txt org-agenda-no-heading-message)) 4015 (setq txt org-agenda-no-heading-message))
3904 (setq priority (org-get-priority txt)) 4016 (setq priority (org-get-priority txt))
3905 (add-text-properties 4017 (add-text-properties
@@ -4044,10 +4156,11 @@ the documentation of `org-diary'."
4044 (abbreviate-file-name (buffer-file-name))))) 4156 (abbreviate-file-name (buffer-file-name)))))
4045 (regexp org-tr-regexp) 4157 (regexp org-tr-regexp)
4046 (d0 (calendar-absolute-from-gregorian date)) 4158 (d0 (calendar-absolute-from-gregorian date))
4047 marker hdmarker ee txt d1 d2 s1 s2) 4159 marker hdmarker ee txt d1 d2 s1 s2 timestr)
4048 (goto-char (point-min)) 4160 (goto-char (point-min))
4049 (while (re-search-forward regexp nil t) 4161 (while (re-search-forward regexp nil t)
4050 (setq s1 (match-string 1) 4162 (setq timestr (match-string 0)
4163 s1 (match-string 1)
4051 s2 (match-string 2) 4164 s2 (match-string 2)
4052 d1 (time-to-days (org-time-string-to-time s1)) 4165 d1 (time-to-days (org-time-string-to-time s1))
4053 d2 (time-to-days (org-time-string-to-time s2))) 4166 d2 (time-to-days (org-time-string-to-time s2)))
@@ -4062,9 +4175,9 @@ the documentation of `org-diary'."
4062 (goto-char (match-end 1)) 4175 (goto-char (match-end 1))
4063 (looking-at "\\*+[ \t]*\\([^\r\n]+\\)") 4176 (looking-at "\\*+[ \t]*\\([^\r\n]+\\)")
4064 (setq txt (org-format-agenda-item 4177 (setq txt (org-format-agenda-item
4065 (format "(%d/%d): " 4178 (format (if (= d1 d2) "" "(%d/%d): ")
4066 (1+ (- d0 d1)) (1+ (- d2 d1))) 4179 (1+ (- d0 d1)) (1+ (- d2 d1)))
4067 (match-string 1)))) 4180 (match-string 1) nil (if (= d0 d1) timestr))))
4068 (setq txt org-agenda-no-heading-message)) 4181 (setq txt org-agenda-no-heading-message))
4069 (add-text-properties 4182 (add-text-properties
4070 0 (length txt) (append (list 'org-marker marker 4183 0 (length txt) (append (list 'org-marker marker
@@ -4077,66 +4190,187 @@ the documentation of `org-diary'."
4077 ;; Sort the entries by expiration date. 4190 ;; Sort the entries by expiration date.
4078 (nreverse ee))) 4191 (nreverse ee)))
4079 4192
4080(defun org-format-agenda-item (prefix txt &optional category) 4193
4194
4195(defconst org-plain-time-of-day-regexp
4196 (concat
4197 "\\(\\<[012]?[0-9]"
4198 "\\(\\(:\\([0-5][0-9]\\([AaPp][Mm]\\)?\\)\\)\\|\\([AaPp][Mm]\\)\\)\\>\\)"
4199 "\\(--?"
4200 "\\(\\<[012]?[0-9]"
4201 "\\(\\(:\\([0-5][0-9]\\([AaPp][Mm]\\)?\\)\\)\\|\\([AaPp][Mm]\\)\\)\\>\\)"
4202 "\\)?")
4203 "Regular expression to match a plain time or time range.
4204Examples: 11:45 or 8am-13:15 or 2:45-2:45pm. After a match, the following
4205groups carry important information:
42060 the full match
42071 the first time, range or not
42088 the second time, if it is a range.")
4209
4210(defconst org-stamp-time-of-day-regexp
4211 (concat
4212 "<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} +[a-zA-Z]+ +\\)"
4213 "\\([012][0-9]:[0-5][0-9]\\)>"
4214 "\\(--?"
4215 "<\\1\\([012][0-9]:[0-5][0-9]\\)>\\)?")
4216 "Regular expression to match a timestamp time or time range.
4217After a match, the following groups carry important information:
42180 the full match
42191 date plus weekday, for backreferencing to make sure both times on same day
42202 the first time, range or not
42214 the second time, if it is a range.")
4222
4223(defvar org-prefix-has-time nil
4224 "A flag, set by `org-compile-prefix-format'.
4225The flag is set if the currently compiled format contains a `%t'.")
4226
4227(defun org-format-agenda-item (extra txt &optional category dotime noprefix)
4081 "Format TXT to be inserted into the agenda buffer. 4228 "Format TXT to be inserted into the agenda buffer.
4082In particular, this indents the line and adds a category." 4229In particular, it adds the prefix and corresponding text properties. EXTRA
4083 (let* ((category (or category 4230must be a string and replaces the `%s' specifier in the prefix format.
4084 org-category 4231CATEGORY (string, symbol or nil) may be used to overule the default
4085 (file-name-sans-extension 4232category taken from local variable or file name. It will replace the `%c'
4086 (file-name-nondirectory (buffer-file-name))))) 4233specifier in the format. DOTIME, when non-nil, indicates that a
4087 (extra prefix) 4234time-of-day should be extracted from TXT for sorting of this entry, and for
4088 (time-of-day (org-get-time-of-day txt)) 4235the `%t' specifier in the format. When DOTIME is a string, this string is
4089 (t1 (if time-of-day (concat "0" (int-to-string time-of-day)) "0000")) 4236searched for a time before TXT is. NOPREFIX is a flag and indicates that
4090 (time (if time-of-day 4237only the correctly processes TXT should be returned - this is used by
4091 (concat (substring t1 -4 -2) 4238`org-agenda-change-all-lines'."
4092 ":" (substring t1 -2)) 4239 (save-match-data
4093 "")) 4240 ;; Diary entries sometimes have extra whitespace at the beginning
4094 rtn) 4241 (if (string-match "^ +" txt) (setq txt (replace-match "" nil nil txt)))
4095 (if (symbolp category) (setq category (symbol-name category))) 4242 (let* ((category (or category
4096 (setq rtn (concat (eval org-prefix-format-compiled) txt)) 4243 org-category
4097 (add-text-properties 4244 (if (buffer-file-name)
4098 0 (length rtn) (list 'category (downcase category) 4245 (file-name-sans-extension
4099 'prefix-length (- (length rtn) (length txt)) 4246 (file-name-nondirectory (buffer-file-name)))
4100 'time-of-day time-of-day) 4247 "")))
4101 rtn) 4248 time ;; needed for the eval of the prefix format
4102 rtn)) 4249 (ts (if dotime (concat (if (stringp dotime) dotime "") txt)))
4103 4250 (time-of-day (and dotime (org-get-time-of-day ts)))
4251 stamp plain s0 s1 s2 rtn)
4252 (when (and dotime time-of-day org-prefix-has-time)
4253 ;; Extract starting and ending time and move them to prefix
4254 (when (or (setq stamp (string-match org-stamp-time-of-day-regexp ts))
4255 (setq plain (string-match org-plain-time-of-day-regexp ts)))
4256 (setq s0 (match-string 0 ts)
4257 s1 (match-string (if plain 1 2) ts)
4258 s2 (match-string (if plain 8 4) ts))
4259
4260 ;; If the times are in TXT (not in DOTIMES), and the prefix will list
4261 ;; them, we might want to remove them there to avoid duplication.
4262 ;; The user can turn this off with a variable.
4263 (if (and org-agenda-remove-times-when-in-prefix (or stamp plain)
4264 (string-match (concat (regexp-quote s0) " *") txt)
4265 (if (eq org-agenda-remove-times-when-in-prefix 'beg)
4266 (= (match-beginning 0) 0)
4267 t))
4268 (setq txt (replace-match "" nil nil txt))))
4269 ;; Normalize the time(s) to 24 hour
4270 (if s1 (setq s1 (org-get-time-of-day s1 'string)))
4271 (if s2 (setq s2 (org-get-time-of-day s2 'string))))
4272
4273 ;; Create the final string
4274 (if noprefix
4275 (setq rtn txt)
4276 ;; Prepare the variables needed in the eval of the compiled format
4277 (setq time (cond (s2 (concat s1 "-" s2))
4278 (s1 (concat s1 "......"))
4279 (t ""))
4280 extra (or extra "")
4281 category (if (symbolp category) (symbol-name category) category))
4282 ;; Evaluate the compiled format
4283 (setq rtn (concat (eval org-prefix-format-compiled) txt)))
4284
4285 ;; And finally add the text properties
4286 (add-text-properties
4287 0 (length rtn) (list 'category (downcase category)
4288 'prefix-length (- (length rtn) (length txt))
4289 'time-of-day time-of-day
4290 'dotime dotime)
4291 rtn)
4292 rtn)))
4293
4294(defun org-agenda-add-time-grid-maybe (list ndays todayp)
4295 (catch 'exit
4296 (cond ((not org-agenda-use-time-grid) (throw 'exit list))
4297 ((and todayp (member 'today (car org-agenda-time-grid))))
4298 ((and (= ndays 1) (member 'daily (car org-agenda-time-grid))))
4299 ((member 'weekly (car org-agenda-time-grid)))
4300 (t (throw 'exit list)))
4301 (let* ((have (delq nil (mapcar
4302 (lambda (x) (get-text-property 1 'time-of-day x))
4303 list)))
4304 (string (nth 1 org-agenda-time-grid))
4305 (gridtimes (nth 2 org-agenda-time-grid))
4306 (req (car org-agenda-time-grid))
4307 (remove (member 'remove-match req))
4308 new time)
4309 (if (and (member 'require-timed req) (not have))
4310 ;; don't show empty grid
4311 (throw 'exit list))
4312 (while (setq time (pop gridtimes))
4313 (unless (and remove (member time have))
4314 (setq time (int-to-string time))
4315 (push (org-format-agenda-item
4316 nil string "" ;; FIXME: put a category?
4317 (concat (substring time 0 -2) ":" (substring time -2)))
4318 new)
4319 (put-text-property
4320 1 (length (car new)) 'face 'org-time-grid-face (car new))))
4321 (if (member 'time-up org-agenda-sorting-strategy)
4322 (append new list)
4323 (append list new)))))
4324
4104(defun org-compile-prefix-format (format) 4325(defun org-compile-prefix-format (format)
4105 "Compile the prefix format into a Lisp form that can be evaluated. 4326 "Compile the prefix format into a Lisp form that can be evaluated.
4106The resulting form is returned and stored in the variable 4327The resulting form is returned and stored in the variable
4107`org-prefix-format-compiled'." 4328`org-prefix-format-compiled'."
4108 (let ((start 0) varform vars (s format) c) 4329 (setq org-prefix-has-time nil)
4109 (while (string-match "%\\([-+]?[0-9.]*\\)\\([ .;,:!?=|/<>]?\\)\\([cts]\\)" 4330 (let ((start 0) varform vars var (s format) c f opt)
4331 (while (string-match "%\\(\\?\\)?\\([-+]?[0-9.]*\\)\\([ .;,:!?=|/<>]?\\)\\([cts]\\)"
4110 s start) 4332 s start)
4111 (setq var (cdr (assoc (match-string 3 s) 4333 (setq var (cdr (assoc (match-string 4 s)
4112 '(("c" . category) ("t" . time) ("s" . extra)))) 4334 '(("c" . category) ("t" . time) ("s" . extra))))
4113 c (match-string 2 s) 4335 c (or (match-string 3 s) "")
4336 opt (match-beginning 1)
4114 start (1+ (match-beginning 0))) 4337 start (1+ (match-beginning 0)))
4115 (if (= (length c) 1) 4338 (if (equal var 'time) (setq org-prefix-has-time t))
4116 (setq varform `(if (equal "" ,var) "" (concat ,var ,c))) 4339 (setq f (concat "%" (match-string 2 s) "s"))
4117 (setq varform var)) 4340 (if opt
4118 (setq s (replace-match "%\\1s" t nil s)) 4341 (setq varform
4342 `(if (equal "" ,var)
4343 ""
4344 (format ,f (if (equal "" ,var) "" (concat ,var ,c)))))
4345 (setq varform `(format ,f (if (equal ,var "") "" (concat ,var ,c)))))
4346 (setq s (replace-match "%s" t nil s))
4119 (push varform vars)) 4347 (push varform vars))
4120 (setq vars (nreverse vars)) 4348 (setq vars (nreverse vars))
4121 (setq org-prefix-format-compiled `(format ,s ,@vars)))) 4349 (setq org-prefix-format-compiled `(format ,s ,@vars))))
4122 4350
4123(defun org-get-time-of-day (s) 4351(defun org-get-time-of-day (s &optional string)
4124 "Check string S for a time of day. 4352 "Check string S for a time of day.
4125If found, return it as a military time number between 0 and 2400. 4353If found, return it as a military time number between 0 and 2400.
4126If not found, return nil." 4354If not found, return nil.
4355The optional STRING argument forces conversion into a 5 character wide string
4356HH:MM."
4127 (save-match-data 4357 (save-match-data
4128 (when (or 4358 (when
4129 (string-match 4359 (or
4130 "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)\\([AaPp][Mm]\\)?\\>" s) 4360 (string-match
4131 (string-match 4361 "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)\\([AaPp][Mm]\\)?\\> *" s)
4132 "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)?\\([AaPp][Mm]\\)\\>" s)) 4362 (string-match
4133 (+ (* 100 (+ (string-to-number (match-string 1 s)) 4363 "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)?\\([AaPp][Mm]\\)\\> *" s))
4134 (if (and (match-beginning 4) 4364 (let* ((t0 (+ (* 100
4135 (equal (downcase (match-string 4 s)) "pm")) 4365 (+ (string-to-number (match-string 1 s))
4136 12 0))) 4366 (if (and (match-beginning 4)
4137 (if (match-beginning 3) 4367 (equal (downcase (match-string 4 s)) "pm"))
4138 (string-to-number (match-string 3 s)) 4368 12 0)))
4139 0))))) 4369 (if (match-beginning 3)
4370 (string-to-number (match-string 3 s))
4371 0)))
4372 (t1 (concat " " (int-to-string t0))))
4373 (if string (concat (substring t1 -4 -2) ":" (substring t1 -2)) t0)))))
4140 4374
4141(defun org-finalize-agenda-entries (list) 4375(defun org-finalize-agenda-entries (list)
4142 "Sort and concatenate the agenda items." 4376 "Sort and concatenate the agenda items."
@@ -4295,23 +4529,30 @@ the same tree node, and the headline of the tree node in the Org-mode file."
4295 4529
4296(defun org-agenda-change-all-lines (newhead hdmarker &optional fixface) 4530(defun org-agenda-change-all-lines (newhead hdmarker &optional fixface)
4297 "Change all lines in the agenda buffer which match hdmarker. 4531 "Change all lines in the agenda buffer which match hdmarker.
4298The new content of the line will be NEWHEAD. HDMARKER is checked with 4532The new content of the line will be NEWHEAD (as modified by
4299`equal' against all `org-hd-marker' text properties in the file." 4533`org-format-agenda-item'). HDMARKER is checked with
4300 (let* (props m pl undone-face done-face) 4534`equal' against all `org-hd-marker' text properties in the file.
4535If FIXFACE is non-nil, the face of each item is modified acording to
4536the new TODO state."
4537 (let* (props m pl undone-face done-face finish new dotime)
4538; (setq newhead (org-format-agenda-item "x" newhead "x" nil 'noprefix))
4301 (save-excursion 4539 (save-excursion
4302 (goto-char (point-max)) 4540 (goto-char (point-max))
4303 (beginning-of-line 1) 4541 (beginning-of-line 1)
4304 (while (not (bobp)) 4542 (while (not finish)
4543 (setq finish (bobp))
4305 (when (and (setq m (get-text-property (point) 'org-hd-marker)) 4544 (when (and (setq m (get-text-property (point) 'org-hd-marker))
4306 (equal m hdmarker)) 4545 (equal m hdmarker))
4307 (setq props (text-properties-at (point)) 4546 (setq props (text-properties-at (point))
4547 dotime (get-text-property (point) 'dotime)
4548 new (org-format-agenda-item "x" newhead "x" dotime 'noprefix)
4308 pl (get-text-property (point) 'prefix-length) 4549 pl (get-text-property (point) 'prefix-length)
4309 undone-face (get-text-property (point) 'undone-face) 4550 undone-face (get-text-property (point) 'undone-face)
4310 done-face (get-text-property (point) 'done-face)) 4551 done-face (get-text-property (point) 'done-face))
4311 (move-to-column pl) 4552 (move-to-column pl)
4312 (if (looking-at ".*") 4553 (if (looking-at ".*")
4313 (progn 4554 (progn
4314 (replace-match newhead t t) 4555 (replace-match new t t)
4315 (beginning-of-line 1) 4556 (beginning-of-line 1)
4316 (add-text-properties (point-at-bol) (point-at-eol) props) 4557 (add-text-properties (point-at-bol) (point-at-eol) props)
4317 (if fixface 4558 (if fixface
@@ -4355,6 +4596,7 @@ the same tree node, and the headline of the tree node in the Org-mode file."
4355 (and (outline-next-heading) 4596 (and (outline-next-heading)
4356 (org-flag-heading nil))) ; show the next heading 4597 (org-flag-heading nil))) ; show the next heading
4357 (funcall 'org-priority force-direction) 4598 (funcall 'org-priority force-direction)
4599 (end-of-line 1)
4358 (setq newhead (org-get-heading))) 4600 (setq newhead (org-get-heading)))
4359 (org-agenda-change-all-lines newhead hdmarker) 4601 (org-agenda-change-all-lines newhead hdmarker)
4360 (beginning-of-line 1))) 4602 (beginning-of-line 1)))
@@ -4519,7 +4761,7 @@ This is a command that has to be installed in `calendar-mode-map'."
4519 "ISO: " (calendar-iso-date-string date) "\n" 4761 "ISO: " (calendar-iso-date-string date) "\n"
4520 "Day of Yr: " (calendar-day-of-year-string date) "\n" 4762 "Day of Yr: " (calendar-day-of-year-string date) "\n"
4521 "Julian: " (calendar-julian-date-string date) "\n" 4763 "Julian: " (calendar-julian-date-string date) "\n"
4522 "Astronomic: " (calendar-astro-date-string date) 4764 "Astron. JD: " (calendar-astro-date-string date)
4523 " (Julian date number at noon UTC)\n" 4765 " (Julian date number at noon UTC)\n"
4524 "Hebrew: " (calendar-hebrew-date-string date) " (until sunset)\n" 4766 "Hebrew: " (calendar-hebrew-date-string date) " (until sunset)\n"
4525 "Islamic: " (calendar-islamic-date-string date) " (until sunset)\n" 4767 "Islamic: " (calendar-islamic-date-string date) " (until sunset)\n"
@@ -4865,10 +5107,11 @@ For file links, arg negates `org-line-numbers-in-file-links'."
4865 ((fboundp 'gnus-group-name) 5107 ((fboundp 'gnus-group-name)
4866 (gnus-group-name)) 5108 (gnus-group-name))
4867 (t "???")))) 5109 (t "???"))))
4868 (setq link (concat (if (org-xor arg org-usenet-links-prefer-google) 5110 (setq link (concat
4869 "http://groups.google.com/groups?group=" 5111 (if (org-xor arg org-usenet-links-prefer-google)
4870 "gnus:") 5112 "http://groups.google.com/groups?group="
4871 group)))) 5113 "gnus:")
5114 group))))
4872 5115
4873 ((memq major-mode '(gnus-summary-mode gnus-article-mode)) 5116 ((memq major-mode '(gnus-summary-mode gnus-article-mode))
4874 (and (eq major-mode 'gnus-article-mode) (gnus-article-show-summary)) 5117 (and (eq major-mode 'gnus-article-mode) (gnus-article-show-summary))
@@ -4919,9 +5162,7 @@ For file links, arg negates `org-line-numbers-in-file-links'."
4919 5162
4920(defun org-xor (a b) 5163(defun org-xor (a b)
4921 "Exclusive or." 5164 "Exclusive or."
4922 ;; (if a (not b) b) 5165 (if a (not b) b))
4923 (or (and a (not b))
4924 (and b (not a))))
4925 5166
4926(defun org-get-header (header) 5167(defun org-get-header (header)
4927 "Find a header field in the current buffer." 5168 "Find a header field in the current buffer."
@@ -5217,7 +5458,8 @@ SIZE is a string Columns x Rows like for example \"3x2\"."
5217 (point-at-bol) (point))) 5458 (point-at-bol) (point)))
5218 (beginning-of-line 1) 5459 (beginning-of-line 1)
5219 (newline)) 5460 (newline))
5220 (mapcar (lambda (x) (insert line)) (make-list rows t)) 5461 ;; (mapcar (lambda (x) (insert line)) (make-list rows t))
5462 (dotimes (i rows) (insert line))
5221 (goto-char pos) 5463 (goto-char pos)
5222 (if (> rows 1) 5464 (if (> rows 1)
5223 ;; Insert a hline after the first row. 5465 ;; Insert a hline after the first row.
@@ -5285,8 +5527,7 @@ Such a file can be imported into a spreadsheet program like Excel."
5285 (unless (or (not (file-exists-p file)) 5527 (unless (or (not (file-exists-p file))
5286 (y-or-n-p (format "Overwrite file %s? " file))) 5528 (y-or-n-p (format "Overwrite file %s? " file)))
5287 (error "Abort")) 5529 (error "Abort"))
5288 (save-excursion 5530 (with-current-buffer (find-file-noselect file)
5289 (find-file file)
5290 (setq buf (current-buffer)) 5531 (setq buf (current-buffer))
5291 (erase-buffer) 5532 (erase-buffer)
5292 (fundamental-mode) 5533 (fundamental-mode)
@@ -5406,12 +5647,18 @@ This is being used to correctly align a single field after TAB or RET.")
5406 (setq rfmt (concat rfmt "\n") 5647 (setq rfmt (concat rfmt "\n")
5407 hfmt (concat (substring hfmt 0 -1) "|\n")) 5648 hfmt (concat (substring hfmt 0 -1) "|\n"))
5408 ;; Produce the new table 5649 ;; Produce the new table
5409 (while lines 5650 ;;(while lines
5410 (setq l (pop lines)) 5651 ;; (setq l (pop lines))
5411 (if l 5652 ;; (if l
5412 (setq new (concat new (apply 'format rfmt 5653 ;; (setq new (concat new (apply 'format rfmt
5413 (append (pop fields) emptystrings)))) 5654 ;; (append (pop fields) emptystrings))))
5414 (setq new (concat new hfmt)))) 5655 ;; (setq new (concat new hfmt))))
5656 (setq new (mapconcat
5657 (lambda (l)
5658 (if l (apply 'format rfmt
5659 (append (pop fields) emptystrings))
5660 hfmt))
5661 lines ""))
5415 ;; Replace the old one 5662 ;; Replace the old one
5416 (delete-region beg end) 5663 (delete-region beg end)
5417 (move-marker end nil) 5664 (move-marker end nil)
@@ -8480,9 +8727,7 @@ to a visible line beginning. This makes the function of C-a more intuitive."
8480 (get-char-property (point) 'invisible)) 8727 (get-char-property (point) 'invisible))
8481 (save-excursion 8728 (save-excursion
8482 (skip-chars-backward "^\r\n") 8729 (skip-chars-backward "^\r\n")
8483 (if (bobp) 8730 (equal (char-before) ?\r))))
8484 nil
8485 (equal (char-before) ?\r)))))
8486 8731
8487(defun org-back-to-heading (&optional invisible-ok) 8732(defun org-back-to-heading (&optional invisible-ok)
8488 "Move to previous heading line, or beg of this line if it's a heading. 8733 "Move to previous heading line, or beg of this line if it's a heading.