emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Paul Sexton <psexton.2a@gmail.com>
To: emacs-orgmode@gnu.org
Subject: Re: Fixes for org-capture-templates-contexts
Date: Mon, 14 Jan 2013 22:21:20 +0000 (UTC)	[thread overview]
Message-ID: <loom.20130114T230538-806@post.gmane.org> (raw)
In-Reply-To: 878v7yu6wf.fsf@bzg.ath.cx

Bastien <bzg <at> altern.org> writes:

> If you can send a patch against master for this, I'd be happy to apply
> it!  Thanks again for pointing to these problems,

Below are patches against org.el and org-capture.el.

Are you sure it works correctly? The following setting for the variable
does causes an error for me out of the box, but does work with the changes
in the patch.

(setq org-capture-templates-contexts
      '(("f" (not-in-file . "\\(espanol\\|verbs\\|nouns\\)\\.org"))
        ("t" (not-in-file . "\\(espanol\\|verbs\\|nouns\\)\\.org"))
        ("e" (in-file . "\\(espanol\\|verbs\\|nouns\\)\\.org"))
        ("m" (in-file . "maths.*\\.org"))
        ("M" (in-file . "med\\.org"))))

Also, very important. I updated to master in order to make the patch and found
the current orgmode does not compile or even load. This is because
ob-eval.el uses 'declare-function' which is undefined (it is defined in
org-macs.el but ob-eval.el does not require that file).

--- ./org.el	2013-01-15 10:54:43.000000000 +1300
+++ /Users/paul/org.el	2013-01-15 11:17:01.000000000 +1300
@@ -8682,9 +8682,11 @@
     (while (setq c (pop a))
       (let (vrules repl)
-	 ((not (assoc (car c) contexts))
+	 ((and (not (assoc (car c) contexts))
+               (not (assoc (string (elt (car c) 0)) contexts)))
 	  (push c r))
-	 ((and (assoc (car c) contexts)
+	 ((and (or (assoc (car c) contexts)
+                   (assoc (string (elt (car c) 0)) contexts))
 	       (setq vrules (org-contextualize-validate-key
 			     (car c) contexts)))
 	  (mapc (lambda (vr)
@@ -8712,27 +8714,49 @@
 (defun org-contextualize-validate-key (key contexts)
   "Check CONTEXTS for agenda or capture KEY."
-  (let (r rr res)
-    (while (setq r (pop contexts))
-      (mapc
-       (lambda (rr)
-	 (when
-	  (and (equal key (car r))
-	       (if (functionp rr) (funcall rr)
-		 (or (and (eq (car rr) 'in-file)
-			  (buffer-file-name)
-			  (string-match (cdr rr) (buffer-file-name)))
-		     (and (eq (car rr) 'in-mode)
-			  (string-match (cdr rr) (symbol-name major-mode)))
-		     (when (and (eq (car rr) 'not-in-file)
-				(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)))))))
-	  (push r res)))
-       (car (last r))))
+  (let (clause context res)
+    (while (setq clause (pop contexts))
+      (let ((context-key (first clause))
+	    (old-key (second clause))
+	    (context-list (cddr clause)))
+        (mapc
+         (lambda (context)
+           (when
+               (cond
+                ((and (>= (length context-key) (length key))
+                      (not (equal key context-key)))
+                 nil)
+                ((and (< (length context-key) (length key))
+                      (not (string-prefix-p context-key key)))
+                 nil)
+                ((functionp context)
+                 (funcall context))
+                (t
+                 (let ((context-spec (first context))
+		       (context-arg (rest context)))
+                   (or (and (eq context-spec 'in-file)
+                            (buffer-file-name)
+                            (string-match context-arg
+                                          (buffer-file-name)))
+                       (and (eq context-spec 'in-buffer)
+                            (string-match context-arg
+                                          (buffer-name)))
+                       (and (eq context-spec 'in-mode)
+                            (eq context-arg major-mode))
+                       (when (and (eq context-spec 'not-in-file)
+                                  (buffer-file-name))
+                         (not (string-match context-arg
+                                            (buffer-file-name))))
+                       (and (eq context-spec 'not-in-buffer)
+                            (not (string-match context-arg
+                                               (buffer-name))))
+                       (when (eq context-spec 'not-in-mode)
+                         (not (eq context-arg major-mode)))))))
+             (push clause res)))
+         context-list)))
     (delete-dups (delq nil res))))
 (defun org-context-p (&rest contexts)
   "Check if local context is any of CONTEXTS.
 Possible values in the list of contexts are `table', `headline', and `item'."

--- ./org-capture.el	2013-01-15 10:54:42.000000000 +1300
+++ /Users/paul/org-capture.el	2013-01-15 11:17:45.000000000 +1300
@@ -449,31 +449,63 @@
 (defcustom org-capture-templates-contexts nil
   "Alist of capture templates and valid contexts.
+Each entry in the alist takes the form:
+   KEY :: a string of one or more letters, identifying a
+       capture template.
+   USUAL-KEY :: if supplied, this is the string that identifies
+       the capture template in `org-capture-templates', while KEY
+       becomes the string which will be used to select the
+       template only in the present context (see below).
+   CONTEXT :: a context definition.
+Each context definition (CONTEXT) takes the form:
+       FUNCTION
+   FUNCTION :: either a lambda form or a symbol naming a function.
+      The function must take no arguments.
+   SPECIFIER :: a symbol matching one of the context specifiers listed
+      below.
+   ARGUMENT :: either a string regular expression (for in-file and
+      in-buffer), or a symbol (for in-mode).
+Here are the available context specifiers:
+      in-file: command displayed in files matching regex
+    in-buffer: command displayed in buffers matching regex
+      in-mode: command displayed if major mode matches symbol
+  not-in-file: command not displayed in files matching regex
+not-in-buffer: command not displayed in buffers matching regex
+  not-in-mode: command not displayed when major mode matches symbol
 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\" ((in-mode . \"message-mode\"))))
-Here are the available contexts definitions:
+   '((\"c\" (in-mode . message-mode)))
-      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 include several context definitions, the agenda command
+will be accessible if at least one of them is valid.
-If you define several checks, the agenda command will be
-accessible if there is at least one valid check.
+If the template specified by KEY has sub-templates, they will also
+be affected by the rule (unless they have their own rules). For
+example, if you have a template `t' and sub-templates `ta', `tb'
+and `tc', then a rule for `t' will affect whether all of those
+contexts are accessible.
 You can also bind a key to another agenda custom command
 depending on contextual rules.
-    '((\"c\" \"d\" ((in-mode . \"message-mode\"))))
+    '((\"c\" \"d\" (in-file . \"\\.el$\") (in-buffer \"scratch\")))
-Here it means: in `message-mode buffers', use \"c\" as the
+Here it means: in files ending in `.el' and in buffers whose
+name contains `scratch', use \"c\" as the
 key for the capture template otherwise associated with \"d\".
-\(The template originally associated with \"d\" is not displayed
+\(The template originally associated with \"q\" is not displayed
 to avoid duplicates.)"
   :version "24.3"
   :group 'org-capture

  reply	other threads:[~2013-01-14 22:21 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-10 21:04 Fixes for org-capture-templates-contexts Paul Sexton
2013-01-11 13:44 ` Darlan Cavalcante Moreira
2013-01-12  8:47   ` Bastien
2013-01-11 17:06 ` Bastien
2013-01-12  8:45 ` Bastien
2013-01-14 22:21   ` Paul Sexton [this message]
2013-01-24 16:08     ` Bastien
2013-01-31 10:07     ` Bastien

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=loom.20130114T230538-806@post.gmane.org \
    --to=psexton.2a@gmail.com \
    --cc=emacs-orgmode@gnu.org \


* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).