summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Guerry <bzg@altern.org>2012-08-23 17:04:43 +0200
committerBastien Guerry <bzg@altern.org>2012-08-24 12:17:58 +0200
commit6c94ea051824edea55356351600875d456325b49 (patch)
tree492b5d701830c2bfed6dc428010818f838511e8c
parentbe70cfd0840c43e1d07fe90031330e425c1e2733 (diff)
downloadorg-mode-6c94ea051824edea55356351600875d456325b49.tar.gz
Implement key replacement depending on the contexts.
* org.el (org-contextualize-agenda-or-capture): Handle key replacement depending on the contexts. * org-capture.el (org-capture-templates-contexts): Allow to use the context as a way to replace one capture template by another one. * org-agenda.el (org-agenda-custom-commands-contexts): Allow to use the context as a way to replace one agenda custom command by another one. * org.texi (Templates in contexts): Document the new structure of the variables `org-agenda-custom-commands-contexts' and `org-capture-templates-contexts'. In the setup below, X is not a real capture template, it is just an alias to templates A and B in .txt and .el files. A and B are deactivated by default in all files. (setq org-capture-templates '(("X" "Nothing but an alias") ("A" "AAAA" entry (file+headline [...])) ("B" "BBBB" entry (file+headline [...])))) (setq org-capture-templates-contexts '(("A" "A" ((not-in-file . ".*"))) ("B" "B" ((not-in-file . ".*"))) ("X" "A" ((in-file . "\\.txt"))) ("X" "B" ((in-file . "\\.el"))))) Thanks to Carsten for suggesting this "key-replacement" idea!
-rw-r--r--doc/org.texi16
-rw-r--r--lisp/org-agenda.el20
-rw-r--r--lisp/org-capture.el22
-rw-r--r--lisp/org.el40
4 files changed, 79 insertions, 19 deletions
diff --git a/doc/org.texi b/doc/org.texi
index 897115c..3ec72b3 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -6863,10 +6863,14 @@ for example that you have a capture template @code{"p"} for storing Gnus
emails containing patches. Then you would configure this option like this:
@example
-(setq org-capture-templates-contexts '(("p" (in-mode . "message-mode"))))
+(setq org-capture-templates-contexts
+ '(("p" "p" (in-mode . "message-mode"))))
@end example
-See the docstring of the variable for more information.
+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.
@node Attachments, RSS Feeds, Capture, Capture - Refile - Archive
@section Attachments
@@ -8778,9 +8782,15 @@ that you only need when reading emails. Then you would configure this option
like this:
@example
-(setq org-agenda-custom-commands-contexts '(("o" (in-mode . "message-mode"))))
+(setq org-agenda-custom-commands-contexts
+ '(("o" "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.
+
See the docstring of the variable for more information.
@node Exporting Agenda Views, Agenda column view, Custom agenda views, Agenda Views
diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index 9c7f29b..563ed3f 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -2341,9 +2341,22 @@ 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\" (in-file . \"\\.txt\")))
+ '((\"p\" \"p\" (in-file . \"\\.txt\")))
-Here are the available checks:
+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:
in-file: command displayed only in matching files
in-mode: command displayed only in matching modes
@@ -2354,8 +2367,9 @@ If you define several checks, the agenda command will be
accessible if there is at least one valid check."
;; :version "24.3"
:group 'org-agenda-custom-commands
- :type '(repeat (cons :tag "Rule"
+ :type '(repeat (list :tag "Rule"
(string :tag "Agenda key")
+ (string :tag "Replace by command")
(repeat :tag "Available when"
(cons :tag "Condition"
(choice
diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index 782e027..368894e 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -442,12 +442,25 @@ for a capture buffer.")
"Bind capture keys with rules on where to display them.
For example, if you have a capture template \"c\" and you want
-this template to be accessible only from message-mode buffers,
+this template to be accessible only from `message-mode' buffers,
use this:
- '((\"c\" (in-mode . \"message-mode\")))
+ '((\"c\" \"c\" (in-mode . \"message-mode\")))
-Here are the available checks:
+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:
+
+ '((\"c\" \"d\" (in-file . \"\\.txt\"))
+ (\"c\" \"e\" (in-file . \"\\.el\"))
+ (\"c\" \"f\" (in-file . \"\\.c\")))
+
+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.
+
+Here are the available contexts definition:
in-file: template displayed only in matching files
in-mode: template displayed only in matching modes
@@ -458,8 +471,9 @@ If you define several checks, the capture template will be
accessible if there is at least one valid check."
;; :version "24.3"
:group 'org-capture
- :type '(repeat (cons :tag "Rule"
+ :type '(repeat (list :tag "Rule"
(string :tag "Capture key")
+ (string :tag "Replace by template")
(repeat :tag "Available when"
(cons :tag "Condition"
(choice
diff --git a/lisp/org.el b/lisp/org.el
index 96b5584..c8b6c54 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -8623,15 +8623,37 @@ to execute outside of tables."
"Return a subset of elements in ALIST depending on CONTEXTS.
ALIST can be either `org-agenda-custom-commands' or
`org-capture-templates'."
- (let ((a alist) c r)
- (while (setq c (pop a))
- (when (or (not (assoc (car c) contexts))
- (and (assoc (car c) contexts)
- (org-rule-validate
- (cdr (assoc (car c) contexts)))))
- (push c r)))
- ;; Return the limited ALIST
- r))
+ (let ((a alist) c r s val repl)
+ (while (setq c (pop a)) ; loop over commands or templates
+ (cond ((not (assoc (car c) contexts))
+ (push c r))
+ ((and (assoc (car c) contexts)
+ (let (rr)
+ (setq val
+ (org-rule-validate
+ (and (mapc ; check all contexts associations
+ (lambda (rl)
+ (when (equal (car rl) (car c))
+ (setq rr (delq nil (append rr (car (last rl)))))))
+ contexts)
+ rr)))))
+ (setq repl
+ (car (delq nil
+ (mapcar (lambda(cnt)
+ (when (and (member (car val) (caddr cnt))
+ (equal (car c) (car cnt))) cnt))
+ contexts))))
+ (unless (equal (car c) (cadr repl))
+ (push (cadr repl) s))
+ (push (cons (car c) (cdr (assoc (cadr repl) alist))) r))))
+ ;; Return limited ALIST, possibly with keys modified, and deduplicated
+ (delq nil
+ (mapcar (lambda(x)
+ (let ((tpl (car x)))
+ (when (not (delq nil
+ (mapcar (lambda(y)
+ (equal y tpl)) s))) x)))
+ r))))
(defun org-rule-validate (rules)
"Check if one of RULES is valid in this buffer."