summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Guerry <bzg@altern.org>2012-08-24 12:14:54 +0200
committerBastien Guerry <bzg@altern.org>2012-08-24 12:18:05 +0200
commit10dbdf5fc28f0346f00e753792553c6d7244457e (patch)
tree32f6029e0ad22cf1c24842a54290a25f87b156da
parent9d73d6d680f991b7477aed8937feec390dfe91b7 (diff)
downloadorg-mode-10dbdf5fc28f0346f00e753792553c6d7244457e.tar.gz
Update the handling of agenda/capture keys contextualization.
* org.el (org-contextualize-keys): Rename from `org-contextualize-agenda-or-capture'. Fix normalization to handle empty key replacement string. (org-contextualize-validate-key): Rename from `org-contexts-validate'. Allow checking against a custom function. * org-agenda.el (org-agenda-custom-commands-contexts): Update. (org-agenda): Use `org-contextualize-keys'. * org-capture.el (org-capture-templates-contexts): Ditto. * org.texi (Templates in contexts, Setting Options): Update to reflect changes in how contexts options are processed.
-rw-r--r--doc/org.texi28
-rw-r--r--lisp/org-agenda.el40
-rw-r--r--lisp/org-capture.el44
-rw-r--r--lisp/org.el28
4 files changed, 77 insertions, 63 deletions
diff --git a/doc/org.texi b/doc/org.texi
index 3ec72b3..c33b5a9 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -6864,13 +6864,18 @@ emails containing patches. Then you would configure this option like this:
@example
(setq org-capture-templates-contexts
- '(("p" "p" (in-mode . "message-mode"))))
+ '(("p" (in-mode . "message-mode"))))
@end example
-The second @code{"p"} tells what template to really call in the specified
-context. You can set this to another capture template, so that @code{p} will
-transparently fall back on it. See the docstring of the variable for more
-information.
+You can also tell that the command key @code{"p"} should refer to another
+template. In that case, add this command key like this:
+
+@example
+(setq org-capture-templates-contexts
+ '(("p" "q" (in-mode . "message-mode"))))
+@end example
+
+See the docstring of the variable for more information.
@node Attachments, RSS Feeds, Capture, Capture - Refile - Archive
@section Attachments
@@ -8783,13 +8788,16 @@ like this:
@example
(setq org-agenda-custom-commands-contexts
- '(("o" "o" (in-mode . "message-mode"))))
+ '(("o" (in-mode . "message-mode"))))
@end example
-The second @code{"o"} tells what command to really call in the specified
-context. You can set this to another agenda custom command, so that @code{o}
-will transparently fall back on it. See the docstring of the variable for
-more information.
+You can also tell that the command key @code{"o"} should refer to another
+command key @code{"r"}. In that case, add this command key like this:
+
+@example
+(setq org-agenda-custom-commands-contexts
+ '(("o" "r" (in-mode . "message-mode"))))
+@end example
See the docstring of the variable for more information.
diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index 563ed3f..20c06ec 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -2335,49 +2335,49 @@ that have been changed along."
(defvar org-agenda-overriding-restriction nil)
(defcustom org-agenda-custom-commands-contexts nil
- "Alist of custom agenda commands and valid contexts.
+ "Alist of custom agenda keys and contextual rules.
For example, if you have a custom agenda command \"p\" and you
want this command to be accessible only from plain text files,
use this:
- '((\"p\" \"p\" (in-file . \"\\.txt\")))
+ '((\"p\" (in-file . \"\\.txt\")))
-If you replace the second \"p\" by another key (say \"q\"), then
-the \"p\" key will be associated with the \"q\" command in the
-valid contexts. This is useful if you want to use the same key
-to reach multiple commands depending on the context:
-
- '((\"p\" \"q\" (in-file . \"\\.txt\"))
- (\"p\" \"r\" (in-file . \"\\.el\"))
- (\"p\" \"s\" (in-file . \"\\.c\")))
-
-Here, the \"p\" key will be accessible from buffers visiting
-.txt, .el and .c files, and it will be a synonym for \"q\", \"r\"
-and \"s\" respectively.
-
-Here are the available contexts definition:
+Here are the available contexts definitions:
in-file: command displayed only in matching files
in-mode: command displayed only in matching modes
not-in-file: command not displayed in matching files
not-in-mode: command not displayed in matching modes
+ [function]: a custom function taking no argument
If you define several checks, the agenda command will be
-accessible if there is at least one valid check."
+accessible if there is at least one valid check.
+
+You can also bind a key to another agenda custom command
+depending on contextual rules.
+
+ '((\"p\" \"q\" (in-file . \"\\.txt\")))
+
+Here it means: in .txt files, use \"p\" as the key for the
+agenda command otherwise associated with \"q\". (The command
+originally associated with \"q\" is not displayed to avoid
+duplicates.)"
;; :version "24.3"
:group 'org-agenda-custom-commands
:type '(repeat (list :tag "Rule"
- (string :tag "Agenda key")
+ (string :tag " Agenda key")
(string :tag "Replace by command")
(repeat :tag "Available when"
+ (choice
(cons :tag "Condition"
(choice
(const :tag "In file" in-file)
(const :tag "Not in file" not-in-file)
(const :tag "In mode" in-mode)
(const :tag "Not in mode" not-in-mode))
- (regexp))))))
+ (regexp))
+ (function :tag "Custom function"))))))
;;;###autoload
(defun org-agenda (&optional arg keys restriction)
@@ -2435,7 +2435,7 @@ Pressing `<' twice means to restrict to the current subtree or region
(t (cons (car x) (cons "" (cdr x))))))
org-agenda-custom-commands)))
(org-agenda-custom-commands
- (org-contextualize-agenda-or-capture
+ (org-contextualize-keys
org-agenda-custom-commands org-agenda-custom-commands-contexts))
(buf (current-buffer))
(bfn (buffer-file-name (buffer-base-buffer)))
diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index 368894e..5cd3b8f 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -439,49 +439,49 @@ for a capture buffer.")
(org-capture)))
(defcustom org-capture-templates-contexts nil
- "Bind capture keys with rules on where to display them.
+ "Alist of capture templates and valid contexts.
For example, if you have a capture template \"c\" and you want
this template to be accessible only from `message-mode' buffers,
use this:
- '((\"c\" \"c\" (in-mode . \"message-mode\")))
+ '((\"c\" (in-mode . \"message-mode\")))
-If you replace the second \"c\" by another key (say \"d\"), then
-the \"c\" key will be associated with the \"d\" template in the
-valid contexts. This is useful if you want to use the same key
-for different templates depending on the context:
+Here are the available contexts definitions:
- '((\"c\" \"d\" (in-file . \"\\.txt\"))
- (\"c\" \"e\" (in-file . \"\\.el\"))
- (\"c\" \"f\" (in-file . \"\\.c\")))
+ in-file: command displayed only in matching files
+ in-mode: command displayed only in matching modes
+ not-in-file: command not displayed in matching files
+ not-in-mode: command not displayed in matching modes
+ [function]: a custom function taking no argument
-Here, the \"c\" key will be accessible from buffers visiting
-.txt, .el and .c files, and it will be a synonym for \"d\", \"e\"
-and \"f\" respectively.
+If you define several checks, the agenda command will be
+accessible if there is at least one valid check.
-Here are the available contexts definition:
+You can also bind a key to another agenda custom command
+depending on contextual rules.
- in-file: template displayed only in matching files
- in-mode: template displayed only in matching modes
- not-in-file: template not displayed in matching files
- not-in-mode: template not displayed in matching modes
+ '((\"c\" \"d\" (in-mode . \"message-mode\")))
-If you define several checks, the capture template will be
-accessible if there is at least one valid check."
+Here it means: in `message-mode buffers', use \"d\" as the
+key for the capture template otherwise associated with \"d\".
+\(The template originally associated with \"q\" is not displayed
+to avoid duplicates.)"
;; :version "24.3"
:group 'org-capture
:type '(repeat (list :tag "Rule"
- (string :tag "Capture key")
+ (string :tag " Capture key")
(string :tag "Replace by template")
(repeat :tag "Available when"
+ (choice
(cons :tag "Condition"
(choice
(const :tag "In file" in-file)
(const :tag "Not in file" not-in-file)
(const :tag "In mode" in-mode)
(const :tag "Not in mode" not-in-mode))
- (regexp))))))
+ (regexp))
+ (function :tag "Custom function"))))))
;;;###autoload
(defun org-capture (&optional goto keys)
@@ -1327,7 +1327,7 @@ Use PREFIX as a prefix for the name of the indirect buffer."
"Select a capture template.
Lisp programs can force the template by setting KEYS to a string."
(let ((org-capture-templates
- (or (org-contextualize-agenda-or-capture
+ (or (org-contextualize-keys
org-capture-templates org-capture-templates-contexts)
'(("t" "Task" entry (file+headline "" "Tasks")
"* TODO %?\n %u\n %a")))))
diff --git a/lisp/org.el b/lisp/org.el
index 5f0ad6a..b3ae268 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -8619,16 +8619,21 @@ to execute outside of tables."
keys)
'('orgstruct-error))))))))
-(defun org-contextualize-agenda-or-capture (alist contexts)
- "Return a subset of elements in ALIST depending on CONTEXTS.
-ALIST can be either `org-agenda-custom-commands' or
-`org-capture-templates'."
+(defun org-contextualize-keys (alist contexts)
+ "Return valid elements in ALIST depending on CONTEXTS.
+
+`org-agenda-custom-commands' or `org-capture-templates' are the
+values used for ALIST, and `org-agenda-custom-commands-contexts'
+or `org-capture-templates-contexts' are the associated contexts
+definitions."
(let ((contexts
;; normalize contexts
(mapcar
- (lambda(c) (if (listp (cadr c))
- (list (car c) (car c) (cadr c))
- c)) contexts))
+ (lambda(c) (cond ((listp (cadr c))
+ (list (car c) (car c) (cadr c)))
+ ((string= "" (cadr c))
+ (list (car c) (car c) (caddr c)))
+ (t c))) contexts))
(a alist) c r s)
;; loop over all commands or templates
(while (setq c (pop a))
@@ -8637,7 +8642,7 @@ ALIST can be either `org-agenda-custom-commands' or
((not (assoc (car c) contexts))
(push c r))
((and (assoc (car c) contexts)
- (setq vrules (org-contexts-validate
+ (setq vrules (org-contextualize-validate-key
(car c) contexts)))
(mapc (lambda (vr)
(when (not (equal (car vr) (cadr vr)))
@@ -8662,8 +8667,8 @@ ALIST can be either `org-agenda-custom-commands' or
(equal y tpl)) s))) x)))
(reverse r))))))
-(defun org-contexts-validate (key contexts)
- "Return valid CONTEXTS."
+(defun org-contextualize-validate-key (key contexts)
+ "Check CONTEXTS for agenda or capture KEY."
(let (r rr res)
(while (setq r (pop contexts))
(mapc
@@ -8679,7 +8684,8 @@ ALIST can be either `org-agenda-custom-commands' or
(buffer-file-name))
(not (string-match (cdr rr) (buffer-file-name))))
(when (eq (car rr) 'not-in-mode)
- (not (string-match (cdr rr) (symbol-name major-mode))))))
+ (not (string-match (cdr rr) (symbol-name major-mode))))
+ (when (functionp rr) (funcall rr))))
(push r res)))
(car (last r))))
(delete-dups (delq nil res))))