diff options
Diffstat (limited to 'lisp/org/org.el')
-rw-r--r-- | lisp/org/org.el | 225 |
1 files changed, 182 insertions, 43 deletions
diff --git a/lisp/org/org.el b/lisp/org/org.el index 340737be939..8171a0271f6 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -5,7 +5,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 6.13a +;; Version: 6.14 ;; ;; This file is part of GNU Emacs. ;; @@ -92,7 +92,7 @@ ;;; Version -(defconst org-version "6.13a" +(defconst org-version "6.14" "The version number of the file org.el.") (defun org-version (&optional here) @@ -143,7 +143,7 @@ With prefix arg HERE, insert it at point." (let ((a (member 'org-infojs org-modules))) (and a (setcar a 'org-jsinfo)))) -(defcustom org-modules '(org-bbdb org-bibtex org-gnus org-info org-jsinfo org-irc org-mew org-mhe org-rmail org-vm org-wl) +(defcustom org-modules '(org-bbdb org-bibtex org-gnus org-info org-jsinfo org-irc org-mew org-mhe org-rmail org-vm org-w3m org-wl) "Modules that should always be loaded together with org.el. If a description starts with <C>, the file is not part of Emacs and loading it will require that you have downloaded and properly installed @@ -172,6 +172,7 @@ to add the symbol `xyz', and the package must have a call to (const :tag " rmail: Links to RMAIL folders/messages" org-rmail) (const :tag " vm: Links to VM folders/messages" org-vm) (const :tag " wl: Links to Wanderlust folders/messages" org-wl) + (const :tag " w3m: Special cut/past from w3m to Org." org-w3m) (const :tag " mouse: Additional mouse support" org-mouse) (const :tag "C annotate-file: Annotate a file with org syntax" org-annotate-file) @@ -955,6 +956,40 @@ It should match if the message is from the user him/herself." :group 'org-link-store :type 'regexp) +(defcustom org-link-to-org-use-id 'create-if-interactive + "Non-nil means, storing a link to an Org file will use entry ID's. + +Note that before this variable is even considered, org-id must be loaded, +to please customize `org-modules' and turn it on. + +The variable can have the following values: + +t Create an ID if needed to make a link to the current entry. + +create-if-interactive + If `org-store-link' is called directly (interactively, as a user + command), do create an ID to support the link. But when doing the + job for remember, only use the ID if it already exists. The + purpose of this setting is to avoid proliferation of unwanted + ID's, just because you happen to be in an Org file when you + call `org-remember' that automatically and preemptively + creates a link. If you do want to get an ID link in a remember + template to an entry not having an ID, create it first by + explicitly creating a link to it, using `C-c C-l' first. + +use-existing + Use existing ID, do not create one. + +nil Never use an ID to make a link, instead link using a text search for + the headline text." + :group 'org-link-store + :type '(choice + (const :tag "Create ID to make link" t) + (const :tag "Create if string link interactively" + 'create-if-interactive) + (const :tag "Only use existing" 'use-existing) + (const :tag "Do not use ID to create link" nil))) + (defcustom org-context-in-file-links t "Non-nil means, file links from `org-store-link' contain context. A search string will be added to the file name with :: as separator and @@ -1881,13 +1916,16 @@ the tags are again aligned to `org-tags-column'." (defcustom org-use-tag-inheritance t "Non-nil means, tags in levels apply also for sublevels. When nil, only the tags directly given in a specific line apply there. -If this option is t, a match early-on in a tree can lead to a large -number of matches in the subtree. If you only want to see the first -match in a tree during a search, check out the variable -`org-tags-match-list-sublevels'. - This may also be a list of tags that should be inherited, or a regexp that -matches tags that should be inherited." +matches tags that should be inherited. Additional control is possible +with the variable `org-tags-exclude-from-inheritance' which gives an +explicit list of tags to be excluded from inheritance., even if the value of +`org-use-tag-inheritance' would select it for inheritance. + +If this option is t, a match early-on in a tree can lead to a large +number of matches in the subtree when constructing the agenda or creating +a sparse tree. If you only want to see the first match in a tree during +a search, check out the variable `org-tags-match-list-sublevels'." :group 'org-tags :type '(choice (const :tag "Not" nil) @@ -1895,9 +1933,18 @@ matches tags that should be inherited." (repeat :tag "Specific tags" (string :tag "Tag")) (regexp :tag "Tags matched by regexp"))) +(defcustom org-tags-exclude-from-inheritance nil + "List of tags that should never be inherited. +This is a way to exclude a few tags from inheritance. For way to do +the opposite, to actively allow inheritance for selected tags, +see the variable `org-use-tag-inheritance'." + :group 'org-tags + :type '(repeat (string :tag "Tag"))) + (defun org-tag-inherit-p (tag) "Check if TAG is one that should be inherited." (cond + ((member tag org-tags-exclude-from-inheritance) nil) ((eq org-use-tag-inheritance t) t) ((not org-use-tag-inheritance) nil) ((stringp org-use-tag-inheritance) @@ -1917,7 +1964,11 @@ inheritance off, you very likely want to turn this option on. As a special case, if the tag search is restricted to TODO items, the value of this variable is ignored and sublevels are always checked, to -make sure all corresponding TODO items find their way into the list." +make sure all corresponding TODO items find their way into the list. + +This variable is semi-obsolete and probably should always be true. It +is better to limit inheritance to certain tags using the variables +`org-use-tag-inheritanc'e and `org-tags-exclude-from-inheritance'." :group 'org-tags :type 'boolean) @@ -2353,9 +2404,9 @@ Use customize to modify this, or restart Emacs after changing it." :group 'org) (defcustom org-completion-use-ido nil - "Non-ni means, use ido completion wherever possible." + "Non-nil means, use ido completion wherever possible." :group 'org-completion - :type 'boolean) + :type 'boolean) (defcustom org-completion-fallback-command 'hippie-expand "The expansion command called by \\[org-complete] in normal context. @@ -2640,6 +2691,17 @@ If yes, offer to stop it and to save the buffer with the changes." (when (org-match-line "#\\+BEGIN: clocktable\\>") (org-clocktable-shift dir n))) +;; Autoload org-timer.el + +;(declare-function org-timer "org-timer") + +(eval-and-compile + (org-autoload + "org-timer" + '(org-timer-start org-timer org-timer-item + org-timer-change-times-in-region))) + + ;; Autoload archiving code ;; The stuff that is needed for cycling and tags has to be defined here. @@ -2778,11 +2840,12 @@ collapsed state." ;; Autoload ID code +(declare-function org-id-store-link "org-id") (org-autoload "org-id" '(org-id-get-create org-id-new org-id-copy org-id-get org-id-get-with-outline-path-completion org-id-get-with-outline-drilling - org-id-goto org-id-find)) + org-id-goto org-id-find org-id-store-link)) ;;; Variables for pre-computed regular expressions, all buffer local @@ -3693,6 +3756,7 @@ will be prompted for." (defvar org-target-link-regexp nil "Regular expression matching radio targets in plain text.") +(make-variable-buffer-local 'org-target-link-regexp) (defvar org-target-regexp "<<\\([^<>\n\r]+\\)>>" "Regular expression matching a link target.") (defvar org-radio-target-regexp "<<<\\([^<>\n\r]+\\)>>>" @@ -3915,6 +3979,8 @@ between words." nil) ;; Priorities (list (concat "\\[#[A-Z0-9]\\]") '(0 'org-special-keyword t)) + ;; Tags + '(org-font-lock-add-tag-faces) ;; Special keywords (list (concat "\\<" org-deadline-string) '(0 'org-special-keyword t)) (list (concat "\\<" org-scheduled-string) '(0 'org-special-keyword t)) @@ -3974,6 +4040,22 @@ If KWD is a number, get the corresponding match group." (and (member kwd org-done-keywords) 'org-done) 'org-todo)) +(defun org-font-lock-add-tag-faces (limit) + "Add the special tag faces." + (when (and org-tag-faces org-tags-special-faces-re) + (while (re-search-forward org-tags-special-faces-re limit t) + (add-text-properties (match-beginning 1) (match-end 1) + (list 'face (org-get-tag-face 1) + 'font-lock-fontified t)) + (backward-char 1)))) + +(defun org-get-tag-face (kwd) + "Get the right face for a TODO keyword KWD. +If KWD is a number, get the corresponding match group." + (if (numberp kwd) (setq kwd (match-string kwd))) + (or (cdr (assoc kwd org-tag-faces)) + 'org-tag)) + (defun org-unfontify-region (beg end &optional maybe_loudly) "Remove fontification and activation overlays from links." (font-lock-default-unfontify-region beg end) @@ -5060,8 +5142,8 @@ is signaled in this case." (setq txt (buffer-substring beg end)) (org-save-markers-in-region beg end) (delete-region beg end) - (outline-flag-region (1- beg) beg nil) - (outline-flag-region (1- (point)) (point) nil) + (or (= beg (point-min)) (outline-flag-region (1- beg) beg nil)) + (or (bobp) (outline-flag-region (1- (point)) (point) nil)) (let ((bbb (point))) (insert-before-markers txt) (org-reinstall-markers-in-region bbb) @@ -5221,6 +5303,7 @@ the inserted text when done." (beginning-of-line 1) (unless for-yank (org-back-over-empty-lines)) (setq beg (point)) + (and (fboundp 'org-id-paste-tracker) (org-id-paste-tracker txt)) (insert-before-markers txt) (unless (string-match "\n\\'" txt) (insert "\n")) (setq newend (point)) @@ -6094,7 +6177,6 @@ type. For a simple example of an export function, see `org-bbdb.el'." (setcdr (assoc type org-link-protocols) (list follow export)) (push (list type follow export) org-link-protocols))) - ;;;###autoload (defun org-store-link (arg) "\\<org-mode-map>Store an org-link to the current location. @@ -6155,14 +6237,34 @@ For file links, arg negates `org-context-in-file-links'." link (org-make-link cpltxt))) ((and buffer-file-name (org-mode-p)) - ;; Just link to current headline - (setq cpltxt (concat "file:" - (abbreviate-file-name buffer-file-name))) - ;; Add a context search string - (when (org-xor org-context-in-file-links arg) - ;; Check if we are on a target - (if (org-in-regexp "<<\\(.*?\\)>>") - (setq cpltxt (concat cpltxt "::" (match-string 1))) + (cond + ((org-in-regexp "<<\\(.*?\\)>>") + (setq cpltxt + (concat "file:" + (abbreviate-file-name buffer-file-name) + "::" (match-string 1)) + link (org-make-link cpltxt))) + ((and (featurep 'org-id) + (or (eq org-link-to-org-use-id t) + (and (eq org-link-to-org-use-id 'create-if-interactive) + (interactive-p)) + (and org-link-to-org-use-id + (condition-case nil + (org-entry-get nil "ID") + (error nil))))) + ;; We can make a link using the ID. + (setq link (condition-case nil + (org-id-store-link) + (error + ;; probably before first headling, link to file only + (concat "file:" + (abbreviate-file-name buffer-file-name)))))) + (t + ;; Just link to current headline + (setq cpltxt (concat "file:" + (abbreviate-file-name buffer-file-name))) + ;; Add a context search string + (when (org-xor org-context-in-file-links arg) (setq txt (cond ((org-on-heading-p) nil) ((org-region-active-p) @@ -6174,10 +6276,10 @@ For file links, arg negates `org-context-in-file-links'." (condition-case nil (org-make-org-heading-search-string txt) (error ""))) - desc "NONE")))) - (if (string-match "::\\'" cpltxt) - (setq cpltxt (substring cpltxt 0 -2))) - (setq link (org-make-link cpltxt))) + desc "NONE"))) + (if (string-match "::\\'" cpltxt) + (setq cpltxt (substring cpltxt 0 -2))) + (setq link (org-make-link cpltxt))))) ((buffer-file-name (buffer-base-buffer)) ;; Just link to this file here. @@ -6889,7 +6991,7 @@ application the system uses for this file type." (format "Execute \"%s\" as elisp? " (org-add-props cmd nil 'face 'org-warning)))) - (message "%s => %s" cmd + (message "%s => %s" cmd (if (equal (string-to-char cmd) ?\() (eval (read cmd)) (call-interactively (read cmd)))) @@ -9026,8 +9128,14 @@ only lines with a TODO keyword are included in the output." ;; compile tags for current headline (setq tags-list (if org-use-tag-inheritance - (apply 'append (mapcar 'cdr tags-alist)) + (apply 'append (mapcar 'cdr (reverse tags-alist))) tags)) + (when org-use-tag-inheritance + (setcdr (car tags-alist) + (mapcar (lambda (x) + (setq x (copy-sequence x)) + (org-add-prop-inherited x)) + (cdar tags-alist)))) (when (and tags org-use-tag-inheritance (not (eq t org-use-tag-inheritance))) ;; selective inheritance, remove uninherited ones @@ -9083,15 +9191,22 @@ only lines with a TODO keyword are included in the output." (defun org-remove-uniherited-tags (tags) "Remove all tags that are not inherited from the list TAGS." (cond - ((eq org-use-tag-inheritance t) tags) + ((eq org-use-tag-inheritance t) + (if org-tags-exclude-from-inheritance + (org-delete-all org-tags-exclude-from-inheritance tags) + tags)) ((not org-use-tag-inheritance) nil) ((stringp org-use-tag-inheritance) (delq nil (mapcar - (lambda (x) (if (string-match org-use-tag-inheritance x) x nil)) + (lambda (x) + (if (and (string-match org-use-tag-inheritance x) + (not (member x org-tags-exclude-from-inheritance))) + x nil)) tags))) ((listp org-use-tag-inheritance) (delq nil (mapcar - (lambda (x) (if (member x org-use-tag-inheritance) x nil)) + (lambda (x) + (if (member x org-use-tag-inheritance) x nil)) tags))))) (defvar todo-only) ;; dynamically scoped @@ -9301,12 +9416,20 @@ epoch to the beginning of today (00:00)." (append '(0 0 0) (nthcdr 3 (decode-time)))))) (defun org-matcher-time (s) - (cond - ((string= s "<now>") (float-time)) - ((string= s "<today>") (org-time-today)) - ((string= s "<tomorrow>") (+ 86400.0 (org-time-today))) - ((string= s "<yesterday>") (- (org-time-today) 86400.0)) - (t (org-2ft s)))) + "Interprete a time comparison value." + (save-match-data + (cond + ((string= s "<now>") (float-time)) + ((string= s "<today>") (org-time-today)) + ((string= s "<tomorrow>") (+ 86400.0 (org-time-today))) + ((string= s "<yesterday>") (- (org-time-today) 86400.0)) + ((string-match "^<\\([-+][0-9]+\\)\\([dwmy]\\)>$" s) + (+ (org-time-today) + (* (string-to-number (match-string 1 s)) + (cdr (assoc (match-string 2 s) + '(("d" . 86400.0) ("w" . 604800.0) + ("m" . 2678400.0) ("y" . 31557600.0))))))) + (t (org-2ft s))))) (defun org-match-any-p (re list) "Does re match any element of list?" @@ -9348,6 +9471,8 @@ ignore inherited ones." (when (looking-at (org-re "[^\r\n]+?:\\([[:alnum:]_@:]+\\):[ \t]*$")) (setq ltags (org-split-string (org-match-string-no-properties 1) ":")) + (when parent + (setq ltags (mapcar 'org-add-prop-inherited ltags))) (setq tags (append (if parent (org-remove-uniherited-tags ltags) @@ -9360,6 +9485,10 @@ ignore inherited ones." (error nil))))) (append (org-remove-uniherited-tags org-file-tags) tags)))) +(defun org-add-prop-inherited (s) + (add-text-properties 0 (length s) '(inherited t) s) + s) + (defun org-toggle-tag (tag &optional onoff) "Toggle the tag TAG for the current line. If ONOFF is `on' or `off', don't toggle but set to this state." @@ -9842,7 +9971,7 @@ the scanner. The following items can be given here: (org-agenda-skip-function (car (org-delete-all '(comment archive) skip))) (org-tags-match-list-sublevels t) - matcher pos file + matcher pos file res org-todo-keywords-for-agenda org-done-keywords-for-agenda org-todo-keyword-alist-for-agenda @@ -9851,7 +9980,7 @@ the scanner. The following items can be given here: (cond ((eq match t) (setq matcher t)) ((eq match nil) (setq matcher t)) - (t (setq matcher (if match (org-make-tags-matcher match) t)))) + (t (setq matcher (if match (cdr (org-make-tags-matcher match)) t)))) (when (eq scope 'tree) (org-back-to-heading t) @@ -9884,7 +10013,8 @@ the scanner. The following items can be given here: (save-restriction (widen) (goto-char (point-min)) - (org-scan-tags func matcher)))))))) + (setq res (append res (org-scan-tags func matcher))))))) + res))) ;;;; Properties @@ -10484,6 +10614,7 @@ completion." IDENT can be a string, a symbol or a number, this function will search for the string representation of it. Return the position where this entry starts, or nil if there is no such entry." + (interactive "sID: ") (let ((id (cond ((stringp ident) ident) ((symbol-name ident) (symbol-name ident)) @@ -12418,6 +12549,10 @@ The images can be removed again with \\[org-ctrl-c-ctrl-c]." (org-defkey org-mode-map "\C-c\C-xp" 'org-set-property) (org-defkey org-mode-map "\C-c\C-xi" 'org-insert-columns-dblock) +(org-defkey org-mode-map "\C-c\C-x." 'org-timer) +(org-defkey org-mode-map "\C-c\C-x-" 'org-timer-item) +(org-defkey org-mode-map "\C-c\C-x0" 'org-timer-start) + (define-key org-mode-map "\C-c\C-x\C-c" 'org-columns) (when (featurep 'xemacs) @@ -13191,7 +13326,11 @@ See the individual commands for more information." :style radio :selected org-display-custom-times] "--" ["Goto Calendar" org-goto-calendar t] - ["Date from Calendar" org-date-from-calendar t]) + ["Date from Calendar" org-date-from-calendar t] + "--" + ["Start/restart timer" org-timer-start t] + ["Insert timer string" org-timer t] + ["Insert timer item" org-timer-item t]) ("Logging work" ["Clock in" org-clock-in t] ["Clock out" org-clock-out t] |