aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarsten Dominik2005-12-16 14:31:22 +0000
committerCarsten Dominik2005-12-16 14:31:22 +0000
commit4da1a99df4ee252174626e38570688dd342d9237 (patch)
tree79080b5f975f870c5f96e6bbb257e3677bf97874
parentf63bdfca444ecfb122ff1d0a789b44b7a296e3e5 (diff)
downloademacs-4da1a99df4ee252174626e38570688dd342d9237.tar.gz
emacs-4da1a99df4ee252174626e38570688dd342d9237.zip
(org-tags-match-list-sublevels): New option.
(org-open-at-point): implement tag searches as links (org-fit-agenda-window, org-get-buffer-tags, org-get-tags) (org-make-tags-matcher, org-scan-tags, org-activate-tags): New functions (org-tags-sparse-tree, org-tags-view, org-set-tags) (org-agenda-dispatch): New commands. (org-use-tag-inheritance, org-tags-column): New options. (org-tab-follows-link, org-return-follows-link): New options. (org-tags): New customize group. (org-start-icalendar-file): Get local time zone. (org-tags-completion-function): New function. (org-set-font-lock-defaults): make sure links will also be highlighted inside headlines.
-rw-r--r--lisp/textmodes/org.el548
1 files changed, 475 insertions, 73 deletions
diff --git a/lisp/textmodes/org.el b/lisp/textmodes/org.el
index 5ffdd1d91b4..2e79be9e4cc 100644
--- a/lisp/textmodes/org.el
+++ b/lisp/textmodes/org.el
@@ -3,9 +3,9 @@
3;; Copyright (c) 2004, 2005 Free Software Foundation 3;; Copyright (c) 2004, 2005 Free Software Foundation
4;; 4;;
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, wp
7;; Homepage: http://www.astro.uva.nl/~dominik/Tools/org/ 7;; Homepage: http://www.astro.uva.nl/~dominik/Tools/org/
8;; Version: 3.24 8;; Version: 4.00
9;; 9;;
10;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
11;; 11;;
@@ -59,7 +59,6 @@
59;; (autoload 'org-mode "org" "Org mode" t) 59;; (autoload 'org-mode "org" "Org mode" t)
60;; (autoload 'org-diary "org" "Diary entries from Org mode") 60;; (autoload 'org-diary "org" "Diary entries from Org mode")
61;; (autoload 'org-agenda "org" "Multi-file agenda from Org mode" t) 61;; (autoload 'org-agenda "org" "Multi-file agenda from Org mode" t)
62;; (autoload 'org-todo-list "org" "Multi-file todo list from Org mode" t)
63;; (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)
64;; (autoload 'orgtbl-mode "org" "Org tables as a minor mode" t) 63;; (autoload 'orgtbl-mode "org" "Org tables as a minor mode" t)
65;; (autoload 'turn-on-orgtbl "org" "Org tables as a minor mode") 64;; (autoload 'turn-on-orgtbl "org" "Org tables as a minor mode")
@@ -82,6 +81,12 @@
82;; 81;;
83;; Changes: 82;; Changes:
84;; ------- 83;; -------
84;; Version 4.00
85;; - Headlines can contain TAGS, and Org-mode can produced a list
86;; of matching headlines based on a TAG search expression.
87;; - `org-agenda' has now become a dispatcher that will produce the agenda
88;; and other views on org-mode data with an additional keypress.
89;;
85;; Version 3.24 90;; Version 3.24
86;; - Switching and item to DONE records a time stamp when the variable 91;; - Switching and item to DONE records a time stamp when the variable
87;; `org-log-done' is turned on. Default is off. 92;; `org-log-done' is turned on. Default is off.
@@ -261,7 +266,7 @@
261 266
262;;; Customization variables 267;;; Customization variables
263 268
264(defvar org-version "3.24" 269(defvar org-version "4.00"
265 "The version number of the file org.el.") 270 "The version number of the file org.el.")
266(defun org-version () 271(defun org-version ()
267 (interactive) 272 (interactive)
@@ -971,11 +976,56 @@ first line, so it is probably best to use this in combinations with
971 :group 'org-structure 976 :group 'org-structure
972 :type 'boolean) 977 :type 'boolean)
973 978
979(defgroup org-tags nil
980 "Options concerning startup of Org-mode."
981 :tag "Org Tags"
982 :group 'org)
983
984(defcustom org-tags-column 40
985 "The column to which tags should be indented in a headline.
986If this number is positive, it specified the column. If it is negative,
987it means that the tags should be flushright to that column. For example,
988-79 works well for a normal 80 character screen."
989 :group 'org-tags
990 :type 'integer)
991
992(defcustom org-use-tag-inheritance t
993 "Non-nil means, tags in levels apply also for sublevels.
994When nil, only the tags directly give in a specific line apply there."
995 :group 'org-tags
996 :type 'boolean)
997
998(defcustom org-tags-match-list-sublevels nil
999 "Non-nil means list also sublevels of headlines matching tag search.
1000Because of tag inheritance (see variable `org-use-tag-inheritance'),
1001the sublevels of a headline matching a tag search often also match
1002the same search. Listing all of them can create very long lists.
1003Setting this variable to nil causes subtrees to be skipped."
1004 :group 'org-tags
1005 :type 'boolean)
1006
1007(defvar org-tags-history nil
1008 "History of minibuffer reads for tags.")
1009(defvar org-last-tags-completion-table nil
1010 "The last used completion table for tags.")
1011
974(defgroup org-link nil 1012(defgroup org-link nil
975 "Options concerning links in Org-mode." 1013 "Options concerning links in Org-mode."
976 :tag "Org Link" 1014 :tag "Org Link"
977 :group 'org) 1015 :group 'org)
978 1016
1017(defcustom org-tab-follows-link nil
1018 "Non-nil means, on links TAB will follow the link.
1019Needs to be set before org.el is loaded."
1020 :group 'org-link
1021 :type 'boolean)
1022
1023(defcustom org-return-follows-link nil
1024 "Non-nil means, on links RET will follow the link.
1025Needs to be set before org.el is loaded."
1026 :group 'org-link
1027 :type 'boolean)
1028
979(defcustom org-link-format "<%s>" 1029(defcustom org-link-format "<%s>"
980 "Default format for linkes in the buffer. 1030 "Default format for linkes in the buffer.
981This is a format string for printf, %s will be replaced by the link text. 1031This is a format string for printf, %s will be replaced by the link text.
@@ -2094,6 +2144,12 @@ The following commands are available:
2094 (if org-xemacs-p [button2] [mouse-2]) 'org-open-at-mouse) 2144 (if org-xemacs-p [button2] [mouse-2]) 'org-open-at-mouse)
2095(define-key org-mouse-map 2145(define-key org-mouse-map
2096 (if org-xemacs-p [button3] [mouse-3]) 'org-find-file-at-mouse) 2146 (if org-xemacs-p [button3] [mouse-3]) 'org-find-file-at-mouse)
2147(when org-tab-follows-link
2148 (define-key org-mouse-map [(tab)] 'org-open-at-point)
2149 (define-key org-mouse-map "\C-i" 'org-open-at-point))
2150(when org-return-follows-link
2151 (define-key org-mouse-map [(return)] 'org-open-at-point)
2152 (define-key org-mouse-map "\C-m" 'org-open-at-point))
2097 2153
2098(require 'font-lock) 2154(require 'font-lock)
2099 2155
@@ -2160,6 +2216,14 @@ The following commands are available:
2160 'keymap org-mouse-map)) 2216 'keymap org-mouse-map))
2161 t))) 2217 t)))
2162 2218
2219(defun org-activate-tags (limit)
2220 (if (re-search-forward "[ \t]\\(:[A-Za-z_:]+:\\)[ \r\n]" limit t)
2221 (progn
2222 (add-text-properties (match-beginning 1) (match-end 1)
2223 (list 'mouse-face 'highlight
2224 'keymap org-mouse-map))
2225 t)))
2226
2163(defun org-font-lock-level () 2227(defun org-font-lock-level ()
2164 (save-excursion 2228 (save-excursion
2165 (org-back-to-heading t) 2229 (org-back-to-heading t)
@@ -2177,14 +2241,13 @@ The following commands are available:
2177(defun org-set-font-lock-defaults () 2241(defun org-set-font-lock-defaults ()
2178 (let ((org-font-lock-extra-keywords 2242 (let ((org-font-lock-extra-keywords
2179 (list 2243 (list
2180 '(org-activate-links (0 'org-link)) 2244 '(org-activate-links (0 'org-link t))
2181 '(org-activate-dates (0 'org-link)) 2245 '(org-activate-dates (0 'org-link t))
2182 '(org-activate-camels (0 'org-link)) 2246 '(org-activate-camels (0 'org-link t))
2247 '(org-activate-tags (1 'org-link t))
2183 (list (concat "^\\*+[ \t]*" org-not-done-regexp) 2248 (list (concat "^\\*+[ \t]*" org-not-done-regexp)
2184 '(1 'org-warning t)) 2249 '(1 'org-warning t))
2185 (list (concat "\\[#[A-Z]\\]") '(0 'org-special-keyword t)) 2250 (list (concat "\\[#[A-Z]\\]") '(0 'org-special-keyword t))
2186; (list (concat "\\<" org-deadline-string) '(0 'org-warning t))
2187; (list (concat "\\<" org-scheduled-string) '(0 'org-warning t))
2188 (list (concat "\\<" org-deadline-string) '(0 'org-special-keyword t)) 2251 (list (concat "\\<" org-deadline-string) '(0 'org-special-keyword t))
2189 (list (concat "\\<" org-scheduled-string) '(0 'org-special-keyword t)) 2252 (list (concat "\\<" org-scheduled-string) '(0 'org-special-keyword t))
2190 (list (concat "\\<" org-closed-string) '(0 'org-special-keyword t)) 2253 (list (concat "\\<" org-closed-string) '(0 'org-special-keyword t))
@@ -2217,7 +2280,7 @@ The following commands are available:
2217 ; on XEmacs if noutline is ever ported 2280 ; on XEmacs if noutline is ever ported
2218 `((eval . (list "^\\(\\*+\\).*" 2281 `((eval . (list "^\\(\\*+\\).*"
2219 ,(if org-level-color-stars-only 1 0) 2282 ,(if org-level-color-stars-only 1 0)
2220 '(nth ;; FIXME: 1<->0 ???? 2283 '(nth
2221 (% (- (match-end 1) (match-beginning 1) 1) 2284 (% (- (match-end 1) (match-beginning 1) 1)
2222 org-n-levels) 2285 org-n-levels)
2223 org-level-faces) 2286 org-level-faces)
@@ -2908,7 +2971,7 @@ If optional TXT is given, check this string instead of the current kill."
2908 (throw 'exit nil))) 2971 (throw 'exit nil)))
2909 t)))) 2972 t))))
2910 2973
2911;;; Plain list item 2974;;; Plain list items
2912 2975
2913(defun org-at-item-p () 2976(defun org-at-item-p ()
2914 "Is point in a line starting a hand-formatted item?" 2977 "Is point in a line starting a hand-formatted item?"
@@ -3069,7 +3132,7 @@ with something like \"1.\" or \"2)\"."
3069 (col (current-column)) 3132 (col (current-column))
3070 (ind (org-get-string-indentation 3133 (ind (org-get-string-indentation
3071 (buffer-substring (point-at-bol) (match-beginning 3)))) 3134 (buffer-substring (point-at-bol) (match-beginning 3))))
3072 (term (substring (match-string 3) -1)) 3135 ;; (term (substring (match-string 3) -1))
3073 ind1 (n (1- arg))) 3136 ind1 (n (1- arg)))
3074 ;; find where this list begins 3137 ;; find where this list begins
3075 (catch 'exit 3138 (catch 'exit
@@ -3134,7 +3197,6 @@ with something like \"1.\" or \"2)\"."
3134 (beginning-of-line 2)) 3197 (beginning-of-line 2))
3135 (goto-char beg))) 3198 (goto-char beg)))
3136 3199
3137
3138;;; Archiving 3200;;; Archiving
3139 3201
3140(defun org-archive-subtree () 3202(defun org-archive-subtree ()
@@ -3250,16 +3312,20 @@ At all other locations, this simply calls `ispell-complete-word'."
3250 (interactive "P") 3312 (interactive "P")
3251 (catch 'exit 3313 (catch 'exit
3252 (let* ((end (point)) 3314 (let* ((end (point))
3315 (beg1 (save-excursion
3316 (if (equal (char-before (point)) ?\ ) (backward-char 1))
3317 (skip-chars-backward "a-zA-Z_")
3318 (point)))
3253 (beg (save-excursion 3319 (beg (save-excursion
3254 (if (equal (char-before (point)) ?\ ) (backward-char 1)) 3320 (if (equal (char-before (point)) ?\ ) (backward-char 1))
3255 (skip-chars-backward "a-zA-Z0-9_:$") 3321 (skip-chars-backward "a-zA-Z0-9_:$")
3256 (point))) 3322 (point)))
3257 (camel (equal (char-before beg) ?*)) 3323 (camel (equal (char-before beg) ?*))
3324 (tag (equal (char-before beg1) ?:))
3258 (texp (equal (char-before beg) ?\\)) 3325 (texp (equal (char-before beg) ?\\))
3259 (opt (equal (buffer-substring (max (point-at-bol) (- beg 2)) 3326 (opt (equal (buffer-substring (max (point-at-bol) (- beg 2))
3260 beg) 3327 beg)
3261 "#+")) 3328 "#+"))
3262 (pattern (buffer-substring-no-properties beg end))
3263 (completion-ignore-case opt) 3329 (completion-ignore-case opt)
3264 (type nil) 3330 (type nil)
3265 (tbl nil) 3331 (tbl nil)
@@ -3285,7 +3351,10 @@ At all other locations, this simply calls `ispell-complete-word'."
3285 (push (list (org-make-org-heading-camel (match-string 3))) 3351 (push (list (org-make-org-heading-camel (match-string 3)))
3286 tbl))) 3352 tbl)))
3287 tbl) 3353 tbl)
3354 (tag (setq type :tag beg beg1)
3355 (org-get-buffer-tags))
3288 (t (progn (ispell-complete-word arg) (throw 'exit nil))))) 3356 (t (progn (ispell-complete-word arg) (throw 'exit nil)))))
3357 (pattern (buffer-substring-no-properties beg end))
3289 (completion (try-completion pattern table))) 3358 (completion (try-completion pattern table)))
3290 (cond ((eq completion t) 3359 (cond ((eq completion t)
3291 (if (equal type :opt) 3360 (if (equal type :opt)
@@ -3301,9 +3370,9 @@ At all other locations, this simply calls `ispell-complete-word'."
3301 (insert completion) 3370 (insert completion)
3302 (if (get-buffer-window "*Completions*") 3371 (if (get-buffer-window "*Completions*")
3303 (delete-window (get-buffer-window "*Completions*"))) 3372 (delete-window (get-buffer-window "*Completions*")))
3304 (if (and (eq type :todo) 3373 (if (assoc completion table)
3305 (assoc completion table)) 3374 (if (eq type :todo) (insert " ")
3306 (insert " ")) 3375 (if (eq type :tag) (insert ":"))))
3307 (if (and (equal type :opt) (assoc completion table)) 3376 (if (and (equal type :opt) (assoc completion table))
3308 (message "%s" (substitute-command-keys 3377 (message "%s" (substitute-command-keys
3309 "Press \\[org-complete] again to insert example settings")))) 3378 "Press \\[org-complete] again to insert example settings"))))
@@ -3676,6 +3745,7 @@ So these are more for recording a certain time/date."
3676 (insert (format-time-string fmt time)))) 3745 (insert (format-time-string fmt time))))
3677 3746
3678;;; FIXME: Make the function take "Fri" as "next friday" 3747;;; FIXME: Make the function take "Fri" as "next friday"
3748;;; because these are mostly being used to record the current time.
3679(defun org-read-date (&optional with-time to-time) 3749(defun org-read-date (&optional with-time to-time)
3680 "Read a date and make things smooth for the user. 3750 "Read a date and make things smooth for the user.
3681The prompt will suggest to enter an ISO date, but you can also enter anything 3751The prompt will suggest to enter an ISO date, but you can also enter anything
@@ -3812,6 +3882,7 @@ Also, store the cursor date in variable ans2."
3812 (let* ((date (calendar-cursor-to-date)) 3882 (let* ((date (calendar-cursor-to-date))
3813 (time (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date)))) 3883 (time (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date))))
3814 (setq ans2 (format-time-string "%Y-%m-%d" time)))) 3884 (setq ans2 (format-time-string "%Y-%m-%d" time))))
3885 (and org-xemacs-p (sit-for .2))
3815 (select-window sw))) 3886 (select-window sw)))
3816 3887
3817(defun org-calendar-select () 3888(defun org-calendar-select ()
@@ -4108,6 +4179,8 @@ If there is already a time stamp at the cursor position, update it."
4108(defvar org-agenda-redo-command nil) 4179(defvar org-agenda-redo-command nil)
4109(defvar org-agenda-mode-hook nil) 4180(defvar org-agenda-mode-hook nil)
4110 4181
4182(defvar org-agenda-force-single-file nil)
4183
4111;;;###autoload 4184;;;###autoload
4112(defun org-agenda-mode () 4185(defun org-agenda-mode ()
4113 "Mode for time-sorted view on action items in Org-mode files. 4186 "Mode for time-sorted view on action items in Org-mode files.
@@ -4133,9 +4206,14 @@ The following commands are available:
4133 '("Agenda") "Agenda Files" 4206 '("Agenda") "Agenda Files"
4134 (append 4207 (append
4135 (list 4208 (list
4136 ["Edit File List" (customize-variable 'org-agenda-files) t] 4209 (vector
4210 (if (get 'org-agenda-files 'org-restrict)
4211 "Restricted to single file"
4212 "Edit File List")
4213 '(customize-variable 'org-agenda-files)
4214 (not (get 'org-agenda-files 'org-restrict)))
4137 "--") 4215 "--")
4138 (mapcar 'org-file-menu-entry org-agenda-files))) 4216 (mapcar 'org-file-menu-entry (org-agenda-files))))
4139 (org-agenda-set-mode-name) 4217 (org-agenda-set-mode-name)
4140 (apply 4218 (apply
4141 (if (fboundp 'run-mode-hooks) 'run-mode-hooks 'run-hooks) 4219 (if (fboundp 'run-mode-hooks) 'run-mode-hooks 'run-hooks)
@@ -4146,7 +4224,7 @@ The following commands are available:
4146(define-key org-agenda-mode-map " " 'org-agenda-show) 4224(define-key org-agenda-mode-map " " 'org-agenda-show)
4147(define-key org-agenda-mode-map "\C-c\C-t" 'org-agenda-todo) 4225(define-key org-agenda-mode-map "\C-c\C-t" 'org-agenda-todo)
4148(define-key org-agenda-mode-map "o" 'delete-other-windows) 4226(define-key org-agenda-mode-map "o" 'delete-other-windows)
4149(define-key org-agenda-mode-map "l" 'org-agenda-recenter) 4227(define-key org-agenda-mode-map "L" 'org-agenda-recenter)
4150(define-key org-agenda-mode-map "t" 'org-agenda-todo) 4228(define-key org-agenda-mode-map "t" 'org-agenda-todo)
4151(define-key org-agenda-mode-map "." 'org-agenda-goto-today) 4229(define-key org-agenda-mode-map "." 'org-agenda-goto-today)
4152(define-key org-agenda-mode-map "d" 'org-agenda-day-view) 4230(define-key org-agenda-mode-map "d" 'org-agenda-day-view)
@@ -4162,7 +4240,7 @@ The following commands are available:
4162 (int-to-string (pop l)) 'digit-argument))) 4240 (int-to-string (pop l)) 'digit-argument)))
4163 4241
4164(define-key org-agenda-mode-map "f" 'org-agenda-follow-mode) 4242(define-key org-agenda-mode-map "f" 'org-agenda-follow-mode)
4165(define-key org-agenda-mode-map "L" 'org-agenda-log-mode) 4243(define-key org-agenda-mode-map "l" 'org-agenda-log-mode)
4166(define-key org-agenda-mode-map "D" 'org-agenda-toggle-diary) 4244(define-key org-agenda-mode-map "D" 'org-agenda-toggle-diary)
4167(define-key org-agenda-mode-map "g" 'org-agenda-toggle-time-grid) 4245(define-key org-agenda-mode-map "g" 'org-agenda-toggle-time-grid)
4168(define-key org-agenda-mode-map "r" 'org-agenda-redo) 4246(define-key org-agenda-mode-map "r" 'org-agenda-redo)
@@ -4228,12 +4306,12 @@ The following commands are available:
4228 "--" 4306 "--"
4229 ["Rebuild buffer" org-agenda-redo t] 4307 ["Rebuild buffer" org-agenda-redo t]
4230 ["Goto Today" org-agenda-goto-today t] 4308 ["Goto Today" org-agenda-goto-today t]
4231 ["Next Dates" org-agenda-later (local-variable-p 'starting-day)] 4309 ["Next Dates" org-agenda-later (local-variable-p 'starting-day (current-buffer))]
4232 ["Previous Dates" org-agenda-earlier (local-variable-p 'starting-day)] 4310 ["Previous Dates" org-agenda-earlier (local-variable-p 'starting-day (current-buffer))]
4233 "--" 4311 "--"
4234 ["Day View" org-agenda-day-view :active (local-variable-p 'starting-day) 4312 ["Day View" org-agenda-day-view :active (local-variable-p 'starting-day (current-buffer))
4235 :style radio :selected (equal org-agenda-ndays 1)] 4313 :style radio :selected (equal org-agenda-ndays 1)]
4236 ["Week View" org-agenda-week-view :active (local-variable-p 'starting-day) 4314 ["Week View" org-agenda-week-view :active (local-variable-p 'starting-day (current-buffer))
4237 :style radio :selected (equal org-agenda-ndays 7)] 4315 :style radio :selected (equal org-agenda-ndays 7)]
4238 "--" 4316 "--"
4239 ["Show Logbook entries" org-agenda-log-mode 4317 ["Show Logbook entries" org-agenda-log-mode
@@ -4256,6 +4334,63 @@ The following commands are available:
4256 ["Exit and Release Buffers" org-agenda-exit t] 4334 ["Exit and Release Buffers" org-agenda-exit t]
4257 )) 4335 ))
4258 4336
4337;;;###autoload
4338(defun org-agenda (arg)
4339 "Dispatch agenda commands to collect entries to the agenda buffer.
4340Prompts for a character to select a command. Any prefix arg will be passed
4341on to the selected command. Possible selections are:
4342
4343a Call `org-agenda' to display the agenda for the current day or week.
4344t Call `org-todo-list' to display the global todo list.
4345T Call `org-todo-list' to display the global todo list, put
4346 select only entries with a specific TODO keyword.
4347m Call `org-tags-view' to display headlines with tags matching
4348 a condition. The tags condition is a list of positive and negative
4349 selections, like `+WORK+URGENT-WITHBOSS'.
4350M like `m', but select only TODO entries, no ordinary headlines.
4351
4352If the current buffer is in Org-mode and visiting a file, you can also
4353first press `1' to indicate that the agenda should be temporarily
4354restricted to the current file."
4355 (interactive "P")
4356 (let ((restrict-ok (and (buffer-file-name) (eq major-mode 'org-mode)))
4357 c)
4358 (put 'org-agenda-files 'org-restrict nil)
4359 (message"[a]genda [t]odoList [T]odoKwd [m]atchTags [M]atchTagsTodo%s"
4360 (if restrict-ok " [1]JustThisFile" ""))
4361 (setq c (read-char-exclusive))
4362 (message "")
4363 (when (equal c ?1)
4364 (if restrict-ok
4365 (put 'org-agenda-files 'org-restrict (list (buffer-file-name)))
4366 (error "Cannot restrict agenda to current buffer"))
4367 (message "Single file: [a]genda [t]odoList [T]odoKwd [m]atchTags [M]atchTagsTodo")
4368 (setq c (read-char-exclusive))
4369 (message ""))
4370 (cond
4371 ((equal c ?a) (call-interactively 'org-agenda-list))
4372 ((equal c ?t) (call-interactively 'org-todo-list))
4373 ((equal c ?T)
4374 (setq current-prefix-arg (or arg '(4)))
4375 (call-interactively 'org-todo-list))
4376 ((equal c ?m) (call-interactively 'org-tags-view))
4377 ((equal c ?M)
4378 (setq current-prefix-arg (or arg '(4)))
4379 (call-interactively 'org-tags-view))
4380 (t (error "Invalid key")))))
4381
4382(defun org-fit-agenda-window ()
4383 "Fit the window to the buffer size."
4384 (and org-fit-agenda-window
4385 (fboundp 'fit-window-to-buffer)
4386 (fit-window-to-buffer nil (/ (* (frame-height) 3) 4)
4387 (/ (frame-height) 2))))
4388
4389(defun org-agenda-files ()
4390 "Get the list of agenda files."
4391 (or (get 'org-agenda-files 'org-restrict)
4392 org-agenda-files))
4393
4259(defvar org-agenda-markers nil 4394(defvar org-agenda-markers nil
4260 "List of all currently active markers created by `org-agenda'.") 4395 "List of all currently active markers created by `org-agenda'.")
4261(defvar org-agenda-last-marker-time (time-to-seconds (current-time)) 4396(defvar org-agenda-last-marker-time (time-to-seconds (current-time))
@@ -4311,8 +4446,7 @@ When a buffer is unmodified, it is just killed. When modified, it is saved
4311(defun org-timeline (&optional include-all keep-modes) 4446(defun org-timeline (&optional include-all keep-modes)
4312 "Show a time-sorted view of the entries in the current org file. 4447 "Show a time-sorted view of the entries in the current org file.
4313Only entries with a time stamp of today or later will be listed. With 4448Only entries with a time stamp of today or later will be listed. With
4314one \\[universal-argument] prefix argument, past entries will also be listed. 4449\\[universal-argument] prefix, all unfinished TODO items will also be shown,
4315With two \\[universal-argument] prefixes, all unfinished TODO items will also be shown,
4316under the current date. 4450under the current date.
4317If the buffer contains an active region, only check the region for 4451If the buffer contains an active region, only check the region for
4318dates." 4452dates."
@@ -4320,8 +4454,8 @@ dates."
4320 (require 'calendar) 4454 (require 'calendar)
4321 (org-agenda-maybe-reset-markers 'force) 4455 (org-agenda-maybe-reset-markers 'force)
4322 (org-compile-prefix-format org-timeline-prefix-format) 4456 (org-compile-prefix-format org-timeline-prefix-format)
4323 (let* ((dopast (or include-all org-agenda-show-log)) 4457 (let* ((dopast t)
4324 (dotodo (member include-all '((16)))) 4458 (dotodo include-all)
4325 (doclosed org-agenda-show-log) 4459 (doclosed org-agenda-show-log)
4326 (org-agenda-keep-modes keep-modes) 4460 (org-agenda-keep-modes keep-modes)
4327 (entry (buffer-file-name)) 4461 (entry (buffer-file-name))
@@ -4387,7 +4521,7 @@ dates."
4387 (goto-char pos1)))) 4521 (goto-char pos1))))
4388 4522
4389;;;###autoload 4523;;;###autoload
4390(defun org-agenda (&optional include-all start-day ndays keep-modes) 4524(defun org-agenda-list (&optional include-all start-day ndays keep-modes)
4391 "Produce a weekly view from all files in variable `org-agenda-files'. 4525 "Produce a weekly view from all files in variable `org-agenda-files'.
4392The view will be for the current week, but from the overview buffer you 4526The view will be for the current week, but from the overview buffer you
4393will be able to go to other weeks. 4527will be able to go to other weeks.
@@ -4408,7 +4542,7 @@ NDAYS defaults to `org-agenda-ndays'."
4408 (and (null ndays) (equal 1 org-agenda-ndays))) 4542 (and (null ndays) (equal 1 org-agenda-ndays)))
4409 nil org-agenda-start-on-weekday)) 4543 nil org-agenda-start-on-weekday))
4410 (org-agenda-keep-modes keep-modes) 4544 (org-agenda-keep-modes keep-modes)
4411 (files (copy-sequence org-agenda-files)) 4545 (files (copy-sequence (org-agenda-files)))
4412 (win (selected-window)) 4546 (win (selected-window))
4413 (today (time-to-days (current-time))) 4547 (today (time-to-days (current-time)))
4414 (sd (or start-day today)) 4548 (sd (or start-day today))
@@ -4424,7 +4558,7 @@ NDAYS defaults to `org-agenda-ndays'."
4424 (inhibit-redisplay t) 4558 (inhibit-redisplay t)
4425 s e rtn rtnall file date d start-pos end-pos todayp nd) 4559 s e rtn rtnall file date d start-pos end-pos todayp nd)
4426 (setq org-agenda-redo-command 4560 (setq org-agenda-redo-command
4427 (list 'org-agenda (list 'quote include-all) start-day ndays t)) 4561 (list 'org-agenda-list (list 'quote include-all) start-day ndays t))
4428 ;; Make the list of days 4562 ;; Make the list of days
4429 (setq ndays (or ndays org-agenda-ndays) 4563 (setq ndays (or ndays org-agenda-ndays)
4430 nd ndays) 4564 nd ndays)
@@ -4444,7 +4578,7 @@ NDAYS defaults to `org-agenda-ndays'."
4444 (set (make-local-variable 'include-all-loc) include-all) 4578 (set (make-local-variable 'include-all-loc) include-all)
4445 (when (and (or include-all org-agenda-include-all-todo) 4579 (when (and (or include-all org-agenda-include-all-todo)
4446 (member today day-numbers)) 4580 (member today day-numbers))
4447 (setq files org-agenda-files 4581 (setq files (org-agenda-files)
4448 rtnall nil) 4582 rtnall nil)
4449 (while (setq file (pop files)) 4583 (while (setq file (pop files))
4450 (catch 'nextfile 4584 (catch 'nextfile
@@ -4466,7 +4600,7 @@ NDAYS defaults to `org-agenda-ndays'."
4466 (setq start-pos (point)) 4600 (setq start-pos (point))
4467 (if (and start-pos (not end-pos)) 4601 (if (and start-pos (not end-pos))
4468 (setq end-pos (point)))) 4602 (setq end-pos (point))))
4469 (setq files org-agenda-files 4603 (setq files (org-agenda-files)
4470 rtnall nil) 4604 rtnall nil)
4471 (while (setq file (pop files)) 4605 (while (setq file (pop files))
4472 (catch 'nextfile 4606 (catch 'nextfile
@@ -4501,9 +4635,7 @@ NDAYS defaults to `org-agenda-ndays'."
4501 (put-text-property s (1- (point)) 'day d)))) 4635 (put-text-property s (1- (point)) 'day d))))
4502 (goto-char (point-min)) 4636 (goto-char (point-min))
4503 (setq buffer-read-only t) 4637 (setq buffer-read-only t)
4504 (if org-fit-agenda-window 4638 (org-fit-agenda-window)
4505 (fit-window-to-buffer nil (/ (* (frame-height) 3) 4)
4506 (/ (frame-height) 2)))
4507 (unless (and (pos-visible-in-window-p (point-min)) 4639 (unless (and (pos-visible-in-window-p (point-min))
4508 (pos-visible-in-window-p (point-max))) 4640 (pos-visible-in-window-p (point-max)))
4509 (goto-char (1- (point-max))) 4641 (goto-char (1- (point-max)))
@@ -4554,7 +4686,7 @@ for a keyword. A numeric prefix directly selects the Nth keyword in
4554 (set (make-local-variable 'org-todo-keywords) kwds) 4686 (set (make-local-variable 'org-todo-keywords) kwds)
4555 (set (make-local-variable 'org-agenda-redo-command) 4687 (set (make-local-variable 'org-agenda-redo-command)
4556 '(org-todo-list (or current-prefix-arg last-arg) t)) 4688 '(org-todo-list (or current-prefix-arg last-arg) t))
4557 (setq files org-agenda-files 4689 (setq files (org-agenda-files)
4558 rtnall nil) 4690 rtnall nil)
4559 (while (setq file (pop files)) 4691 (while (setq file (pop files))
4560 (catch 'nextfile 4692 (catch 'nextfile
@@ -4580,9 +4712,7 @@ for a keyword. A numeric prefix directly selects the Nth keyword in
4580 (insert (org-finalize-agenda-entries rtnall) "\n")) 4712 (insert (org-finalize-agenda-entries rtnall) "\n"))
4581 (goto-char (point-min)) 4713 (goto-char (point-min))
4582 (setq buffer-read-only t) 4714 (setq buffer-read-only t)
4583 (if org-fit-agenda-window 4715 (org-fit-agenda-window)
4584 (fit-window-to-buffer nil (/ (* (frame-height) 3) 4)
4585 (/ (frame-height) 2)))
4586 (if (not org-select-agenda-window) (select-window win)))) 4716 (if (not org-select-agenda-window) (select-window win))))
4587 4717
4588(defun org-check-agenda-file (file) 4718(defun org-check-agenda-file (file)
@@ -4640,8 +4770,8 @@ With prefix ARG, go forward that many times `org-agenda-ndays'."
4640 (interactive "p") 4770 (interactive "p")
4641 (unless (boundp 'starting-day) 4771 (unless (boundp 'starting-day)
4642 (error "Not allowed")) 4772 (error "Not allowed"))
4643 (org-agenda (if (boundp 'include-all-loc) include-all-loc nil) 4773 (org-agenda-list (if (boundp 'include-all-loc) include-all-loc nil)
4644 (+ starting-day (* arg org-agenda-ndays)) nil t)) 4774 (+ starting-day (* arg org-agenda-ndays)) nil t))
4645 4775
4646(defun org-agenda-earlier (arg) 4776(defun org-agenda-earlier (arg)
4647 "Go back in time by `org-agenda-ndays' days. 4777 "Go back in time by `org-agenda-ndays' days.
@@ -4649,8 +4779,8 @@ With prefix ARG, go back that many times `org-agenda-ndays'."
4649 (interactive "p") 4779 (interactive "p")
4650 (unless (boundp 'starting-day) 4780 (unless (boundp 'starting-day)
4651 (error "Not allowed")) 4781 (error "Not allowed"))
4652 (org-agenda (if (boundp 'include-all-loc) include-all-loc nil) 4782 (org-agenda-list (if (boundp 'include-all-loc) include-all-loc nil)
4653 (- starting-day (* arg org-agenda-ndays)) nil t)) 4783 (- starting-day (* arg org-agenda-ndays)) nil t))
4654 4784
4655(defun org-agenda-week-view () 4785(defun org-agenda-week-view ()
4656 "Switch to weekly view for agenda." 4786 "Switch to weekly view for agenda."
@@ -4658,10 +4788,10 @@ With prefix ARG, go back that many times `org-agenda-ndays'."
4658 (unless (boundp 'starting-day) 4788 (unless (boundp 'starting-day)
4659 (error "Not allowed")) 4789 (error "Not allowed"))
4660 (setq org-agenda-ndays 7) 4790 (setq org-agenda-ndays 7)
4661 (org-agenda include-all-loc 4791 (org-agenda-list include-all-loc
4662 (or (get-text-property (point) 'day) 4792 (or (get-text-property (point) 'day)
4663 starting-day) 4793 starting-day)
4664 nil t) 4794 nil t)
4665 (org-agenda-set-mode-name) 4795 (org-agenda-set-mode-name)
4666 (message "Switched to week view")) 4796 (message "Switched to week view"))
4667 4797
@@ -4671,10 +4801,10 @@ With prefix ARG, go back that many times `org-agenda-ndays'."
4671 (unless (boundp 'starting-day) 4801 (unless (boundp 'starting-day)
4672 (error "Not allowed")) 4802 (error "Not allowed"))
4673 (setq org-agenda-ndays 1) 4803 (setq org-agenda-ndays 1)
4674 (org-agenda include-all-loc 4804 (org-agenda-list include-all-loc
4675 (or (get-text-property (point) 'day) 4805 (or (get-text-property (point) 'day)
4676 starting-day) 4806 starting-day)
4677 nil t) 4807 nil t)
4678 (org-agenda-set-mode-name) 4808 (org-agenda-set-mode-name)
4679 (message "Switched to day view")) 4809 (message "Switched to day view"))
4680 4810
@@ -4939,7 +5069,7 @@ Optional argument FILE means, use this file instead of the current."
4939 5069
4940(defun org-file-menu-entry (file) 5070(defun org-file-menu-entry (file)
4941 (vector file (list 'find-file file) t)) 5071 (vector file (list 'find-file file) t))
4942;; FIXME: Maybe removed a buffer visited through the menu from 5072;; FIXME: Maybe we removed a buffer visited through the menu from
4943;; org-agenda-new-buffers, so that the buffer will not be removed 5073;; org-agenda-new-buffers, so that the buffer will not be removed
4944;; when exiting the agenda???? 5074;; when exiting the agenda????
4945 5075
@@ -5270,7 +5400,7 @@ the documentation of `org-diary'."
5270 (apply 'encode-time ; DATE bound by calendar 5400 (apply 'encode-time ; DATE bound by calendar
5271 (list 0 0 0 (nth 1 date) (car date) (nth 2 date)))) 5401 (list 0 0 0 (nth 1 date) (car date) (nth 2 date))))
5272 1 11)))) 5402 1 11))))
5273 marker hdmarker deadlinep scheduledp donep tmp priority category 5403 marker hdmarker priority category
5274 ee txt timestr) 5404 ee txt timestr)
5275 (goto-char (point-min)) 5405 (goto-char (point-min))
5276 (while (re-search-forward regexp nil t) 5406 (while (re-search-forward regexp nil t)
@@ -5279,7 +5409,8 @@ the documentation of `org-diary'."
5279 (setq marker (org-agenda-new-marker (match-beginning 0)) 5409 (setq marker (org-agenda-new-marker (match-beginning 0))
5280 category (org-get-category (match-beginning 0)) 5410 category (org-get-category (match-beginning 0))
5281 timestr (buffer-substring (match-beginning 0) (point-at-eol)) 5411 timestr (buffer-substring (match-beginning 0) (point-at-eol))
5282 donep (org-entry-is-done-p)) 5412 ;; donep (org-entry-is-done-p)
5413 )
5283 (if (string-match "\\]" timestr) 5414 (if (string-match "\\]" timestr)
5284 ;; substring should only run to end of time stamp 5415 ;; substring should only run to end of time stamp
5285 (setq timestr (substring timestr 0 (match-end 0)))) 5416 (setq timestr (substring timestr 0 (match-end 0))))
@@ -5584,7 +5715,7 @@ only the correctly processes TXT should be returned - this is used by
5584 (unless (and remove (member time have)) 5715 (unless (and remove (member time have))
5585 (setq time (int-to-string time)) 5716 (setq time (int-to-string time))
5586 (push (org-format-agenda-item 5717 (push (org-format-agenda-item
5587 nil string "" ;; FIXME: put a category? 5718 nil string "" ;; FIXME: put a category for the grid?
5588 (concat (substring time 0 -2) ":" (substring time -2))) 5719 (concat (substring time 0 -2) ":" (substring time -2)))
5589 new) 5720 new)
5590 (put-text-property 5721 (put-text-property
@@ -6022,9 +6153,9 @@ argument, latitude and longitude will be prompted for."
6022 "Compute the Org-mode agenda for the calendar date displayed at the cursor. 6153 "Compute the Org-mode agenda for the calendar date displayed at the cursor.
6023This is a command that has to be installed in `calendar-mode-map'." 6154This is a command that has to be installed in `calendar-mode-map'."
6024 (interactive) 6155 (interactive)
6025 (org-agenda nil (calendar-absolute-from-gregorian 6156 (org-agenda-list nil (calendar-absolute-from-gregorian
6026 (calendar-cursor-to-date)) 6157 (calendar-cursor-to-date))
6027 nil t)) 6158 nil t))
6028 6159
6029(defun org-agenda-convert-date () 6160(defun org-agenda-convert-date ()
6030 (interactive) 6161 (interactive)
@@ -6052,6 +6183,259 @@ This is a command that has to be installed in `calendar-mode-map'."
6052 (princ s)) 6183 (princ s))
6053 (fit-window-to-buffer (get-buffer-window "*Dates*")))) 6184 (fit-window-to-buffer (get-buffer-window "*Dates*"))))
6054 6185
6186;;; Tags
6187
6188(defun org-scan-tags (action matcher &optional todo-only)
6189 "Scan headline tags with inheritance and produce output ACTION.
6190ACTION can be `sparse-tree' or `agenda'. MATCHER is a Lisp form to be
6191evaluated, testing if a given set of tags qualifies a headline for
6192inclusion. When TODO-ONLY is non-nil, only lines with a TDOD keyword
6193d are included in the output."
6194 (let* ((re (concat "[\n\r]" outline-regexp " *\\(\\<\\("
6195 (mapconcat 'regexp-quote
6196 (nreverse (cdr (reverse org-todo-keywords)))
6197 "\\|")
6198 "\\>\\)\\)? *\\(.*?\\)\\(:[A-Za-z_:]+:\\)?[ \t]*[\n\r]"))
6199 (props (list 'face nil
6200 'done-face 'org-done
6201 'undone-face nil
6202 'mouse-face 'highlight
6203 'keymap org-agenda-keymap
6204 'help-echo
6205 (format "mouse-2 or RET jump to org file %s"
6206 (abbreviate-file-name (buffer-file-name)))))
6207 tags tags-list tags-alist (llast 0) rtn level category i txt
6208 todo marker)
6209
6210 (save-excursion
6211 (goto-char (point-min))
6212 (when (eq action 'sparse-tree) (hide-sublevels 1))
6213 (while (re-search-forward re nil t)
6214 (setq todo (if (match-end 1) (match-string 2))
6215 tags (if (match-end 4) (match-string 4)))
6216 (goto-char (1+ (match-beginning 0)))
6217 (setq level (outline-level)
6218 category (org-get-category))
6219 (setq i llast llast level)
6220 ;; remove tag lists from same and sublevels
6221 (while (>= i level)
6222 (when (setq entry (assoc i tags-alist))
6223 (setq tags-alist (delete entry tags-alist)))
6224 (setq i (1- i)))
6225 ;; add the nex tags
6226 (when tags
6227 (setq tags (mapcar 'downcase (org-split-string tags ":"))
6228 tags-alist
6229 (cons (cons level tags) tags-alist)))
6230 ;; compile tags for current headline
6231 (setq tags-list
6232 (if org-use-tag-inheritance
6233 (apply 'append (mapcar 'cdr tags-alist))
6234 tags))
6235 (when (and (or (not todo-only) todo)
6236 (eval matcher))
6237 ;; list this headline
6238 (if (eq action 'sparse-tree)
6239 (progn
6240 (org-show-hierarchy-above))
6241 (setq txt (org-format-agenda-item
6242 ""
6243 (concat
6244 (if org-tags-match-list-sublevels
6245 (make-string (1- level) ?.) "")
6246 (org-get-heading))
6247 category))
6248 (setq marker (org-agenda-new-marker))
6249 (add-text-properties
6250 0 (length txt)
6251 (append (list 'org-marker marker 'org-hd-marker marker
6252 'category category)
6253 props)
6254 txt)
6255 (push txt rtn))
6256 ;; if we are to skip sublevels, jump to end of subtree
6257 (or org-tags-match-list-sublevels (outline-end-of-subtree)))))
6258 (nreverse rtn)))
6259
6260(defun org-tags-sparse-tree (&optional arg match)
6261 "Create a sparse tree according to tags search string MATCH.
6262MATCH can contain positive and negative selection of tags, like
6263\"+WORK+URGENT-WITHBOSS\"."
6264 (interactive "P")
6265 (let ((org-show-following-heading nil)
6266 (org-show-hierarchy-above nil))
6267 (org-scan-tags 'sparse-tree (cdr (org-make-tags-matcher match)))))
6268
6269(defun org-make-tags-matcher (match)
6270 "Create the TAGS matcher form for the tags-selecting string MATCH."
6271 (unless match
6272 (setq org-last-tags-completion-table
6273 (or (org-get-buffer-tags)
6274 org-last-tags-completion-table))
6275 (setq match (completing-read
6276 "Tags: " 'org-tags-completion-function nil nil nil
6277 'org-tags-history)))
6278 (let ((match0 match) minus tag mm matcher)
6279 (while (string-match "^\\([-+:]\\)?\\([A-Za-z_]+\\)" match)
6280 (setq minus (and (match-end 1) (equal (string-to-char match) ?-))
6281 tag (match-string 2 match)
6282 match (substring match (match-end 0))
6283 mm (list 'member (downcase tag) 'tags-list)
6284 mm (if minus (list 'not mm) mm))
6285 (push mm matcher))
6286 (cons match0 (cons 'and matcher))))
6287
6288;;;###autoload
6289(defun org-tags-view (&optional todo-only match keep-modes)
6290 "Show all headlines for all `org-agenda-files' matching a TAGS criterions.
6291The prefix arg TODO-ONLY limits the search to TODO entries."
6292 (interactive "P")
6293 (org-agenda-maybe-reset-markers 'force)
6294 (org-compile-prefix-format org-agenda-prefix-format)
6295 (let* ((org-agenda-keep-modes keep-modes)
6296 (win (selected-window))
6297 (completion-ignore-case t)
6298 rtn rtnall files file pos matcher
6299 buffer)
6300 (setq matcher (org-make-tags-matcher match)
6301 match (car matcher) matcher (cdr matcher))
6302 (if (not (equal (current-buffer) (get-buffer org-agenda-buffer-name)))
6303 (progn
6304 (delete-other-windows)
6305 (switch-to-buffer-other-window
6306 (get-buffer-create org-agenda-buffer-name))))
6307 (setq buffer-read-only nil)
6308 (erase-buffer)
6309 (org-agenda-mode) (setq buffer-read-only nil)
6310 (set (make-local-variable 'org-agenda-redo-command)
6311 '(call-interactively 'org-tags-view))
6312 (setq files (org-agenda-files)
6313 rtnall nil)
6314 (while (setq file (pop files))
6315 (catch 'nextfile
6316 (org-check-agenda-file file)
6317 (setq buffer (if (file-exists-p file)
6318 (org-get-agenda-file-buffer file)
6319 (error "No such file %s" file)))
6320 (if (not buffer)
6321 ;; If file does not exist, merror message to agenda
6322 (setq rtn (list
6323 (format "ORG-AGENDA-ERROR: No such org-file %s" file))
6324 rtnall (append rtnall rtn))
6325 (with-current-buffer buffer
6326 (unless (eq major-mode 'org-mode)
6327 (error "Agenda file %s is not in `org-mode'" file))
6328 (save-excursion
6329 (save-restriction
6330 (if org-respect-restriction
6331 (if (org-region-active-p)
6332 ;; Respect a region to restrict search
6333 (narrow-to-region (region-beginning) (region-end)))
6334 ;; If we work for the calendar or many files,
6335 ;; get rid of any restriction
6336 (widen))
6337 (setq rtn (org-scan-tags 'agenda matcher todo-only))
6338 (setq rtnall (append rtnall rtn))))))))
6339 (insert "Headlines with TAGS match: ")
6340 (add-text-properties (point-min) (1- (point))
6341 (list 'face 'org-link))
6342 (setq pos (point))
6343 (insert match "\n")
6344 (add-text-properties pos (1- (point)) (list 'face 'org-warning))
6345 (when rtnall
6346 (insert (mapconcat 'identity rtnall "\n")))
6347 (goto-char (point-min))
6348 (setq buffer-read-only t)
6349 (org-fit-agenda-window)
6350 (if (not org-select-agenda-window) (select-window win))))
6351
6352(defvar org-add-colon-after-tag-completion nil) ;; dynamically skoped param
6353(defun org-set-tags (&optional arg just-align)
6354 "Set the tags for the current headline.
6355With prefix ARG, realign all tags in headings in the current buffer."
6356 (interactive)
6357 (let* (;(inherit (org-get-inherited-tags))
6358 (re (concat "^" outline-regexp))
6359 (col (current-column))
6360 (current (org-get-tags))
6361 tags hd)
6362 (if arg
6363 (save-excursion
6364 (goto-char (point-min))
6365 (while (re-search-forward re nil t)
6366 (org-set-tags nil t))
6367 (message "All tags realigned to column %d" org-tags-column))
6368 (if just-align
6369 (setq tags current)
6370 (setq org-last-tags-completion-table
6371 (or (org-get-buffer-tags);; FIXME: replace +- with :, so that we can use history stuff???
6372 org-last-tags-completion-table))
6373 (setq tags
6374 (let ((org-add-colon-after-tag-completion t))
6375 (completing-read "Tags: " 'org-tags-completion-function
6376 nil nil current 'org-tags-history)))
6377 (while (string-match "[-+]" tags)
6378 (setq tags (replace-match ":" t t tags)))
6379 (unless (string-match ":$" tags) (setq tags (concat tags ":")))
6380 (unless (string-match "^:" tags) (setq tags (concat ":" tags))))
6381 (beginning-of-line 1)
6382 (looking-at (concat "\\(.*\\)\\(" (regexp-quote current) "\\)[ \t]*"))
6383 (setq hd (save-match-data (org-trim (match-string 1))))
6384 (delete-region (match-beginning 0) (match-end 0))
6385 (insert hd " ")
6386 (move-to-column (max (current-column)
6387 (if (> org-tags-column 0)
6388 org-tags-column
6389 (- org-tags-column (length tags))))
6390 t)
6391 (insert tags)
6392 (move-to-column col))))
6393
6394(defun org-tags-completion-function (string predicate &optional flag)
6395 (let (s1 s2 rtn (ctable org-last-tags-completion-table))
6396 (if (string-match "^\\(.*[-+:]\\)\\([^-+:]*\\)$" string)
6397 (setq s1 (match-string 1 string)
6398 s2 (match-string 2 string))
6399 (setq s1 "" s2 string))
6400 (cond
6401 ((eq flag nil)
6402 ;; try completion
6403 (setq rtn (try-completion s2 ctable))
6404 (if (stringp rtn)
6405 (concat s1 s2 (substring rtn (length s2))
6406 (if (and org-add-colon-after-tag-completion
6407 (assoc rtn ctable))
6408 ":" "")))
6409 )
6410 ((eq flag t)
6411 ;; all-completions
6412 (all-completions s2 ctable)
6413 )
6414 ((eq flag 'lambda)
6415 ;; exact match?
6416 (assoc s2 ctable)))
6417 ))
6418
6419(defun org-get-tags ()
6420 "Get the TAGS string in the current headline."
6421 (unless (org-on-heading-p)
6422 (error "Not on a heading"))
6423 (save-excursion
6424 (beginning-of-line 1)
6425 (if (looking-at ".*[ \t]\\(:[A-Za-z_:]+:\\)[ \t]*\\(\r\\|$\\)")
6426 (match-string 1)
6427 "")))
6428
6429(defun org-get-buffer-tags ()
6430 "Get a table of all tags used in the buffer, for completion."
6431 (let (tags)
6432 (save-excursion
6433 (goto-char (point-min))
6434 (while (re-search-forward "[ \t]:\\([A-Za-z_:]+\\):[ \t\r\n]" nil t)
6435 (mapc (lambda (x) (add-to-list 'tags x))
6436 (org-split-string (match-string-no-properties 1) ":"))))
6437 (mapcar 'list tags)))
6438
6055;;; Link Stuff 6439;;; Link Stuff
6056 6440
6057(defun org-find-file-at-mouse (ev) 6441(defun org-find-file-at-mouse (ev)
@@ -6075,9 +6459,9 @@ optional argument IN-EMACS is non-nil, Emacs will visit the file."
6075 (interactive "P") 6459 (interactive "P")
6076 (org-remove-occur-highlights nil nil t) 6460 (org-remove-occur-highlights nil nil t)
6077 (if (org-at-timestamp-p) 6461 (if (org-at-timestamp-p)
6078 (org-agenda nil (time-to-days (org-time-string-to-time 6462 (org-agenda-list nil (time-to-days (org-time-string-to-time
6079 (substring (match-string 1) 0 10))) 6463 (substring (match-string 1) 0 10)))
6080 1) 6464 1)
6081 (let (type path line search (pos (point))) 6465 (let (type path line search (pos (point)))
6082 (catch 'match 6466 (catch 'match
6083 (save-excursion 6467 (save-excursion
@@ -6089,6 +6473,14 @@ optional argument IN-EMACS is non-nil, Emacs will visit the file."
6089 path (match-string 2)) 6473 path (match-string 2))
6090 (throw 'match t))) 6474 (throw 'match t)))
6091 (save-excursion 6475 (save-excursion
6476 (skip-chars-backward "^ \t\n\r")
6477 (when (looking-at "\\(:[A-Za-z_:]+\\):[ \t\r\n]")
6478 (setq type "tags"
6479 path (match-string 1))
6480 (while (string-match ":" path)
6481 (setq path (replace-match "+" t t path)))
6482 (throw 'match t)))
6483 (save-excursion
6092 (skip-chars-backward "a-zA-Z_") 6484 (skip-chars-backward "a-zA-Z_")
6093 (when (looking-at org-camel-regexp) 6485 (when (looking-at org-camel-regexp)
6094 (setq type "camel" path (match-string 0)) 6486 (setq type "camel" path (match-string 0))
@@ -6113,6 +6505,8 @@ optional argument IN-EMACS is non-nil, Emacs will visit the file."
6113 6505
6114 (cond 6506 (cond
6115 6507
6508 ((string= type "tags")
6509 (org-tags-view path in-emacs))
6116 ((string= type "camel") 6510 ((string= type "camel")
6117 (org-link-search 6511 (org-link-search
6118 path 6512 path
@@ -10564,7 +10958,7 @@ When COMBINE is non nil, add the category to each line."
10564 (dts (org-ical-ts-to-string 10958 (dts (org-ical-ts-to-string
10565 (format-time-string (cdr org-time-stamp-formats) (current-time)) 10959 (format-time-string (cdr org-time-stamp-formats) (current-time))
10566 "DTSTART")) 10960 "DTSTART"))
10567 hd ts ts2 state (inc t) pos scheduledp deadlinep donep tmp pri) 10961 hd ts ts2 state (inc t) pos scheduledp deadlinep tmp pri)
10568 (save-excursion 10962 (save-excursion
10569 (goto-char (point-min)) 10963 (goto-char (point-min))
10570 (while (re-search-forward org-ts-regexp nil t) 10964 (while (re-search-forward org-ts-regexp nil t)
@@ -10582,7 +10976,8 @@ When COMBINE is non nil, add the category to each line."
10582 pos) 10976 pos)
10583 deadlinep (string-match org-deadline-regexp tmp) 10977 deadlinep (string-match org-deadline-regexp tmp)
10584 scheduledp (string-match org-scheduled-regexp tmp) 10978 scheduledp (string-match org-scheduled-regexp tmp)
10585 donep (org-entry-is-done-p))) 10979 ;; donep (org-entry-is-done-p)
10980 ))
10586 (if (or (string-match org-tr-regexp hd) 10981 (if (or (string-match org-tr-regexp hd)
10587 (string-match org-ts-regexp hd)) 10982 (string-match org-ts-regexp hd))
10588 (setq hd (replace-match "" t t hd))) 10983 (setq hd (replace-match "" t t hd)))
@@ -10623,9 +11018,8 @@ END:VTODO\n"
10623(defun org-start-icalendar-file (name) 11018(defun org-start-icalendar-file (name)
10624 "Start an iCalendar file by inserting the header." 11019 "Start an iCalendar file by inserting the header."
10625 (let ((user user-full-name) 11020 (let ((user user-full-name)
10626 (calname "something")
10627 (name (or name "unknown")) 11021 (name (or name "unknown"))
10628 (timezone "Europe/Amsterdam")) ;; FIXME: How can I get the real timezone? 11022 (timezone (cadr (current-time-zone))))
10629 (princ 11023 (princ
10630 (format "BEGIN:VCALENDAR 11024 (format "BEGIN:VCALENDAR
10631VERSION:2.0 11025VERSION:2.0
@@ -10727,6 +11121,7 @@ a time), or the day by one (if it does not contain a time)."
10727(define-key org-mode-map "\C-c\C-v" 'org-show-todo-tree) 11121(define-key org-mode-map "\C-c\C-v" 'org-show-todo-tree)
10728(define-key org-mode-map "\C-c\C-w" 'org-check-deadlines) 11122(define-key org-mode-map "\C-c\C-w" 'org-check-deadlines)
10729(define-key org-mode-map "\C-c/" 'org-occur) ; Minor-mode reserved 11123(define-key org-mode-map "\C-c/" 'org-occur) ; Minor-mode reserved
11124(define-key org-mode-map "\C-c\\" 'org-tags-sparse-tree) ; Minor-mode res.
10730(define-key org-mode-map "\C-c\C-m" 'org-insert-heading) 11125(define-key org-mode-map "\C-c\C-m" 'org-insert-heading)
10731(define-key org-mode-map "\M-\C-m" 'org-insert-heading) 11126(define-key org-mode-map "\M-\C-m" 'org-insert-heading)
10732(define-key org-mode-map "\C-c\C-l" 'org-insert-link) 11127(define-key org-mode-map "\C-c\C-l" 'org-insert-link)
@@ -11027,6 +11422,7 @@ See the individual commands for more information."
11027 (org-table-paste-rectangle) 11422 (org-table-paste-rectangle)
11028 (org-paste-subtree arg))) 11423 (org-paste-subtree arg)))
11029 11424
11425;; FIXME: document tags
11030(defun org-ctrl-c-ctrl-c (&optional arg) 11426(defun org-ctrl-c-ctrl-c (&optional arg)
11031 "Call realign table, or recognize a table.el table, or update keywords. 11427 "Call realign table, or recognize a table.el table, or update keywords.
11032When the cursor is inside a table created by the table.el package, 11428When the cursor is inside a table created by the table.el package,
@@ -11039,6 +11435,7 @@ If the cursor is on a #+TBLFM line, re-apply the formulae to the table."
11039 (interactive "P") 11435 (interactive "P")
11040 (let ((org-enable-table-editor t)) 11436 (let ((org-enable-table-editor t))
11041 (cond 11437 (cond
11438 ((org-on-heading-p) (org-set-tags arg))
11042 ((org-at-table.el-p) 11439 ((org-at-table.el-p)
11043 (require 'table) 11440 (require 'table)
11044 (beginning-of-line 1) 11441 (beginning-of-line 1)
@@ -11213,12 +11610,18 @@ See the individual commands for more information."
11213 ["Goto Calendar" org-goto-calendar t] 11610 ["Goto Calendar" org-goto-calendar t]
11214 ["Date from Calendar" org-date-from-calendar t]) 11611 ["Date from Calendar" org-date-from-calendar t])
11215 "--" 11612 "--"
11216 ("Timeline/Agenda" 11613 ("Agenda/Summary Views"
11217 ["Show TODO Tree this File" org-show-todo-tree t] 11614 "Current File"
11218 ["Check Deadlines this File" org-check-deadlines t] 11615 ["TODO Tree" org-show-todo-tree t]
11219 ["Timeline Current File" org-timeline t] 11616 ["Check Deadlines" org-check-deadlines t]
11617 ["Timeline" org-timeline t]
11618 ["Tags Tree" org-tags-sparse-tree t]
11220 "--" 11619 "--"
11221 ["Agenda" org-agenda t]) 11620 "All Agenda Files"
11621 ["Command Dispatcher" org-agenda t]
11622 ["TODO list" org-todo-list t]
11623 ["Agenda" org-agenda-list t]
11624 ["Tags View" org-tags-view t])
11222 ("File List for Agenda") 11625 ("File List for Agenda")
11223 "--" 11626 "--"
11224 ("Hyperlinks" 11627 ("Hyperlinks"
@@ -11610,4 +12013,3 @@ Show the heading too, if it is currently invisible."
11610;;; org.el ends here 12013;;; org.el ends here
11611 12014
11612 12015
11613