From mboxrd@z Thu Jan 1 00:00:00 1970 From: Carsten Dominik Subject: Re: Allowing multiple date trees in a single file Date: Sun, 5 Feb 2017 11:40:33 +0100 Message-ID: References: <87wpdv4fdq.fsf@nicolasgoaziou.fr> <871sw1zice.fsf@nicolasgoaziou.fr> <87y3y8zk52.fsf@nicolasgoaziou.fr> <877f56yvdz.fsf@nicolasgoaziou.fr> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=001a113f9fe23bdb510547c626f1 Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:41506) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1caKFf-0004c0-II for emacs-orgmode@gnu.org; Sun, 05 Feb 2017 05:41:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1caKFb-0007Fj-Gq for emacs-orgmode@gnu.org; Sun, 05 Feb 2017 05:40:59 -0500 Received: from mail-io0-x231.google.com ([2607:f8b0:4001:c06::231]:36632) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1caKFb-0007Ef-8a for emacs-orgmode@gnu.org; Sun, 05 Feb 2017 05:40:55 -0500 Received: by mail-io0-x231.google.com with SMTP id j13so47750821iod.3 for ; Sun, 05 Feb 2017 02:40:54 -0800 (PST) In-Reply-To: <877f56yvdz.fsf@nicolasgoaziou.fr> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: Nicolas Goaziou Cc: org-mode list --001a113f9fe23bdb510547c626f1 Content-Type: text/plain; charset=UTF-8 Hi Nicolas, thank you for taking the time to look at the proposed changes in detail. My replies and comments are below. On Sat, Feb 4, 2017 at 1:48 PM, Nicolas Goaziou wrote: > Hello, > > Carsten Dominik writes: > > > Attached is a patch that does the following: > > > > It consolidates all four different org-capture target types that have to > do > > with > > date/week trees into a single one, called `file+olp+datetree'. This > target > > allows for an optional outline path specification to tell capture to > build > > the > > datetree under a specific headline. To switch to a week tree, or to > force > > a date prompt is now the matter of setting one of the properties in the > > org-capture-template variable. > > It sounds good. Thank you. > Allright. > > > Everything works transparently, so users can update the way they > > write their datetree captures, but they don't have to - the old syntax > > remains > > supported and will automatically switched when one uses customize to > change > > the variable. > > I am a bit worried by this compatibility layer. I mean, it is good to > preserve compatibility with old templates, but it ought to be an > ephemeral solution. I.e., no more > `org-table--error-on-old-row-references' lingering around for ages. > > We could, for example, generate a deprecation warning when old templates > are used. Then we will be able to remove this unnecessary piece of code > in next major release. > We do disagree here a bit. This little bit of extra work just keeps the existing templates working. We do not introduce a really different structure of the org-capture-templates. Rather, the code introduces a new target type, and it makes some older target types be implemented as special versions of the new ones. The old targets are no longer in the manual, any customize user will be switched automatically. What remains is a small bit of code that makes sure that the setup of user who might have been using that for a long time continues to work. In my eyes, this is worth it. Breaking something in a new version is no big deal for people who use Org regularly, but I am sure there are a lot of users out there who have not changed their setup for a long time, have not followed the discussions here and would be frustrated if their setup breaks after getting a new version of Emacs, for example. So we can shoot a warning, but I would vote for just keeping this piece of code indefinitely. > > See for example the end of `org-open-file', although it is a bit more > drastic (it raises an error, not a warning). > > > After a bit more testing, I'd like to apply this patch. Please let me > know > > if you agree. And additional testers would be useful. Anyone? Make sure > > to backup your capture templates if something goes wrong. > > Some comments follow. > > > -@item (file+weektree+prompt "path/to/file") > > -Will create a heading in a week tree, but will prompt for the date. > > +one matched.}. If the optional outline path is given, the tree will be > built > > +under the node it is pointing to. Check out the @code{:time-prompt} and > > There's a missing space above. > I will fix that in the next patch. > > > +(defun org-capture-upgrade-templates (templates) > > + "Update the template list to the new format. > > +The new format unifies all the date/week tree targets into one that > > +also allows for an optional outline path to specify a target." > > + (let (target props) > > + (mapcar > > + (lambda (ee) > > + (setq target (car (nth 3 ee))) > > + (when (memq target '(file+datetree file+datetree+prompt > > + file+weektree > file+weektree+prompt)) > > + (setq target (symbol-name target) props nil) > > + (if (string-match "prompt" target) (setq props '(:time-prompt t))) > > + (if (string-match "week" target) > > + (setq props (append '(:tree-type week) props))) > > + (setcar (nth 3 ee) 'file+olp+datetree) > > + (setcdr (nthcdr 4 ee) (append props (nthcdr 5 ee)))) > > + ee) > > + templates))) > > I suggest the following. Less `setq', `setcar', `setcdr' makes Org > a better place. > > (defun org-capture-upgrade-templates (templates) > "Update the template list to the new format. > TEMPLATES is a template list, as in `org-capture-templates'. The > new format unifies all the date/week tree targets into one that > also allows for an optional outline path to specify a target." > (mapcar > (lambda (template) > (pcase template > ;; Match templates with an obsolete "tree" target type. Replace > ;; it with common `file+olp-datetree'. Add new properties > ;; (i.e., `:time-prompt' and `:tree-type') if needed. > (`(,key ,desc ,type (file+datetree . ,path) ,template . ,props) > `(,key ,desc ,type (file+olp+datetree ,@path) ,@props)) > (`(,key ,desc ,type (file+datetree+prompt . ,path) ,template . > ,props) > `(,key ,desc ,type (file+olp+datetree ,@path) :time-prompt t > ,@props)) > (`(,key ,desc ,type (file+weektree . ,path) ,template . ,props) > `(,key ,desc ,type (file+olp+datetree ,@path) :tree-type week > ,@props)) > (`(,key ,desc ,type (file+weektree+prompt . ,path) ,template . > ,props) > `(,key ,desc ,type (file+olp+datetree ,@path) :tree-type week > :time-prompt t ,@props)) > ;; Other templates are left unchanged. > (_ template))) > templates)) > OK, no objections to a different implementation. I am not familiar with pcase, looks general and useful, should learn about it. > > > - (file+weektree+prompt \"path/to/file\") > > - Will create a heading in a week tree, prompts for date > > + (file+olp+datetree \"path/to/file\" \"Level 1 heading\" > ...) > > + Will create a heading in a date tree for today's date. > > + If no headings are given, the tree will be on top > level. > > Nitpick: It may be just me, but "If no heading is given" sounds better. > OK. > > > ELisp programs can set KEYS to a string associated with a template > > in `org-capture-templates'. In this case, interactive selection > > will be bypassed. > > @@ -902,6 +920,7 @@ Store them in the capture property list." > > (insert "* " headline "\n") > > (beginning-of-line 0))) > > (`(file+olp ,path . ,outline-path) > > + (setq outline-path (org-capture-sanitize-olp outline-path)) > > See below about `org-capture-sanitize-olp'. > > Also, it is better to make the `setq' a let-binding when possible. > Hmm, maybe I misunderstand pcase. I was under the impression that when pcase does the match, it will bind the path to outline-path locally (with let or something similar), so that I can, in the scope of the current match, use setq to change the variable. Is my understanding incorrect here? > > (let ((m (org-find-olp (cons (org-capture-expand-file path) > > outline-path)))) > > (set-buffer (marker-buffer m)) > > @@ -922,59 +941,65 @@ Store them in the capture property list." > > (org-capture-put :exact-position (point)) > > (setq target-entry-p > > (and (derived-mode-p 'org-mode) (org-at-heading-p))))) > > [...] > > > + (`(file+olp+datetree ,path . ,outline-path) > > + (setq outline-path (org-capture-sanitize-olp outline-path)) > > Ditto. > > > + (let ((m (if outline-path > > + (org-find-olp (cons (org-capture-expand-file path) > > + outline-path)) > > + (set-buffer (org-capture-target-buffer path)) > > + (move-marker (make-marker) (point))))) > > + (set-buffer (marker-buffer m)) > > + (org-capture-put-target-region-and-position) > > + (widen) > > + (goto-char m) > > + (set-marker m nil) > > + (require 'org-datetree) > > + (org-capture-put-target-region-and-position) > > + (widen) > > + ;; Make a date/week tree entry, with the current date (or > > + ;; yesterday, if we are extending dates for a couple of hours) > > + (funcall > > + (if (eq (org-capture-get :tree-type) 'week) > > + #'org-datetree-find-iso-week-create > > + #'org-datetree-find-date-create) > > + (calendar-gregorian-from-absolute > > + (cond > > + (org-overriding-default-time > > + ;; Use the overriding default time. > > + (time-to-days org-overriding-default-time)) > > + ((org-capture-get :time-prompt) > > + ;; Prompt for date. > > + (let ((prompt-time (org-read-date > > + nil t nil "Date for tree entry:" > > + (current-time)))) > > + (org-capture-put > > + :default-time > > + (cond ((and (or (not (boundp 'org-time-was-given)) > > + (not org-time-was-given)) > > + (not (= (time-to-days prompt-time) > (org-today)))) > > + ;; Use 00:00 when no time is given for another > > + ;; date than today? > > + (apply #'encode-time > > + (append '(0 0 0) > > + (cl-cdddr (decode-time > prompt-time))))) > > + ((string-match "\\([^ ]+\\)--?[^ ]+[ ]+\\(.*\\)" > > + org-read-date-final-answer) > > + ;; Replace any time range by its start. > > + (apply #'encode-time > > + (org-read-date-analyze > > + (replace-match "\\1 \\2" nil nil > > + org-read-date-final-answer) > > + prompt-time (decode-time prompt-time)))) > > + (t prompt-time))) > > + (time-to-days prompt-time))) > > + (t > > + ;; Current date, possibly corrected for late night > > + ;; workers. > > + (org-today)))) > > + ;; the following is the keep-restriction argument for > > + ;; org-datetree-find-date-create > > ;; The following... > ;; ... `org-datetree-find-date-create'. > > > + (if outline-path 'subtree-at-point) > > (and outline-path 'subtree-at-point) > > > + ))) > > These trailing parens need to be moved above. > OK. > > > (`(file+function ,path ,function) > > (set-buffer (org-capture-target-buffer path)) > > (org-capture-put-target-region-and-position) > > @@ -1432,6 +1457,13 @@ Use PREFIX as a prefix for the name of the > indirect buffer." > > (unless (org-kill-is-subtree-p tree) > > (error "Template is not a valid Org entry or tree"))) > > > > +(defun org-capture-sanitize-olp (olp) > > + "Keep only non-white strings in the list OPL." > > + (let (res e) > > + (while (setq e (pop olp)) > > + (and (stringp e) (string-match "\\S-" e) (push e res))) > > + (nreverse res))) > > This function is really a one-liner: > > (cl-remove-if-not #'org-string-nw-p olp) > > Therefore, I don't think it deserves a dedicated function. > > BTW is there any reason to prune non-white strings from the list? Is an > empty string even invalid, since document can contain blank headlines? > > The outline path is provided by the user. We can assume he knows what he > is doing. > > Another option would be to barf if the outline path contains any invalid > value instead of silently "fixing" it on user's behalf. E.g., > > (when (cl-some #'invalid-value-check olp) > (user-error "Invalid outline path in template %S" template)) > > for some value of #'invalid-value-check. > > WDYT? > Well, I agree with you that we should not even have this code in here. It is a hack to solve an issue I was not able to crack - maybe you can. Let me explain: When I use customize to insert a template definition with the new file+olp+datetree target, I want the outline path to be optional. Here is the relevant part of the customize type definition: (list :tag "File [ & Outline path ] & Date tree" (const :format "" file+olp+datetree) ,file-variants (repeat :tag "Outline path" :inline t (string :tag "Headline"))) The problem is that customize sets this up assuming at least one string, in the customize buffer it looks like this Target location: Value Menu File [ & Outline path ] & Date tree: Filename : Value Menu Literal: Outline path: INS DEL Headline: INS Template : Value Menu String: As you can see, without the user clicking INS, there is already a string there. So the user would have to click DEL to make the old empty. I figured people would forget all the time, therefore the hack to remove empty headlines. It is critical that the outline path to be empty, because that is used to decide if the date trree will be on top level or under a heading. Do you or anyone know how to tweak customize to start out with an empty OLP for this application? The we can remove that part entirely. Otherwise, I am happy to make it a oneliner. > > > When it is nil, the buffer will be widened to make sure an existing date > > -tree can be found." > > +tree can be found. If it is the sympol `subtree-at-point', then the > tree > > +will be built under the headline at point." > > (setq-local org-datetree-base-level 1) > > - (or keep-restriction (widen)) > > (save-restriction > > - (let ((prop (org-find-property "DATE_TREE"))) > > - (when prop > > - (goto-char prop) > > - (setq-local org-datetree-base-level > > - (org-get-valid-level (org-current-level) 1)) > > - (org-narrow-to-subtree))) > > + (if (eq keep-restriction 'subtree-at-point) > > + (progn > > + (or (org-at-heading-p) (error "Not at heading")) > > Nitpick: > > (unless (org-at-heading-p) (error "Not at heading")) > OK > > > + (widen) > > + (org-narrow-to-subtree) > > + (setq-local org-datetree-base-level > > + (org-get-valid-level (org-current-level) 1))) > > + (or keep-restriction (widen)) > > (unless keep-restriction (widen)) > OK > > > + ;; support the old way of tree placement, using a property > > ;; Support ... using a property. > OK > > > + (let ((prop (org-find-property "DATE_TREE"))) > > + (when prop > > + (goto-char prop) > > + (setq-local org-datetree-base-level > > + (org-get-valid-level (org-current-level) 1)) > > + (org-narrow-to-subtree)))) > > (goto-char (point-min)) > > (let ((year (calendar-extract-year d)) > > (month (calendar-extract-month d)) > > @@ -84,18 +93,26 @@ tree can be found." > > "Find or create an ISO week entry for date D. > > Compared to `org-datetree-find-date-create' this function creates > > entries ordered by week instead of months. > > -If KEEP-RESTRICTION is non-nil, do not widen the buffer. When it > > -is nil, the buffer will be widened to make sure an existing date > > -tree can be found." > > +When it is nil, the buffer will be widened to make sure an existing date > > +tree can be found. If it is the sympol `subtree-at-point', then the > tree > > +will be built under the headline at point." > > (setq-local org-datetree-base-level 1) > > - (or keep-restriction (widen)) > > (save-restriction > > - (let ((prop (org-find-property "WEEK_TREE"))) > > - (when prop > > - (goto-char prop) > > - (setq-local org-datetree-base-level > > - (org-get-valid-level (org-current-level) 1)) > > - (org-narrow-to-subtree))) > > + (if (eq keep-restriction 'subtree-at-point) > > + (progn > > + (or (org-at-heading-p) (error "Not at heading")) > > + (widen) > > + (org-narrow-to-subtree) > > + (setq-local org-datetree-base-level > > + (org-get-valid-level (org-current-level) 1))) > > + (or keep-restriction (widen)) > > + ;; support the old way of tree placement, using a property > > + (let ((prop (org-find-property "WEEK_TREE"))) > > + (when prop > > + (goto-char prop) > > + (setq-local org-datetree-base-level > > + (org-get-valid-level (org-current-level) 1)) > > + (org-narrow-to-subtree)))) > > See above, since the same suggestions apply. Also, it looks like there > is some code duplication involved here. Would it make sense to factor > the common part out of them? > I'll take a look if it does make sense and do it if it is easy. I see it as a separate issue since the week tree was implemented using a copy of the date tree function. But I can merge this change into the patch I am making. > > > (goto-char (point-min)) > > (require 'cal-iso) > > (let* ((year (calendar-extract-year d)) > > Modified lisp/org.el > > diff --git a/lisp/org.el b/lisp/org.el > > index 38fce70..ac56d71 100644 > > --- a/lisp/org.el > > +++ b/lisp/org.el > > @@ -16615,6 +16615,8 @@ only headings." > > end found flevel) > > (unless buffer (error "File not found :%s" file)) > > (with-current-buffer buffer > > + (unless (derived-mode-p 'org-mode) > > + (error "Buffer %s needs to be in org-mode" buffer)) > > Nitpick: "Buffer %s needs to be in Org mode" > OK > > Ideally, a bunch of tests in test-org-capture.el would be nice. > Will do so after we have converged. Regards Carsten > > > Regards, > > -- > Nicolas Goaziou > --001a113f9fe23bdb510547c626f1 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi Nicolas,

thank you for taking the ti= me to look at the proposed changes in detail.=C2=A0 My replies and comments= are below.

= On Sat, Feb 4, 2017 at 1:48 PM, Nicolas Goaziou <mail@nicolasgoaziou.= fr> wrote:
Hello,

Carsten Dominik <dominik@uva.nl>= ; writes:

> Attached is a patch that does the follow= ing:
>
> It consolidates all four different org-capture target types that have = to do
> with
> date/week trees into a single one, called `file+olp+datetree'.=C2= =A0 This target
> allows for an optional outline path specification to tell capture to b= uild
> the
> datetree under a specific headline.=C2=A0 To switch to a week tree, or= to force
> a date prompt is now the matter of setting one of the properties in th= e
> org-capture-template variable.

It sounds good. Thank you.

Allri= ght.
=C2=A0

> Everything works transparently, so users can update the way they
> write their datetree captures, but they don't have to - the old sy= ntax
> remains
> supported and will automatically switched when one uses customize to c= hange
> the variable.

I am a bit worried by this compatibility layer. I mean, it is good t= o
preserve compatibility with old templates, but it ought to be an
ephemeral solution. I.e., no more
`org-table--error-on-old-row-references' lingering around for ages= .

We could, for example, generate a deprecation warning when old templates are used. Then we will be able to remove this unnecessary piece of code
in next major release.

We do disagree h= ere a bit.=C2=A0 This little bit of extra work just keeps the existing temp= lates working.=C2=A0 We do not introduce a really different structure of th= e org-capture-templates.=C2=A0 Rather, the code introduces a new target typ= e, and it makes some older target types be implemented as special versions = of the new ones.=C2=A0 The old targets are no longer in the manual, any cus= tomize user will be switched automatically.=C2=A0 What remains is a small b= it of code that makes sure that the setup of user who might have been using= that for a long time continues to work.

In my eye= s, this is worth it.=C2=A0 Breaking something in a new version is no big de= al for people who use Org regularly, but I am sure there are a lot of users= out there who have not changed their setup for a long time, have not follo= wed the discussions here and would be frustrated if their setup breaks afte= r getting a new version of Emacs, for example.=C2=A0 So we can shoot a warn= ing, but I would vote for just keeping this piece of code indefinitely.
=C2=A0

See for example the end of `org-open-file', although it is a bit more drastic (it raises an error, not a warning).

> After a bit more testing, I'd like to apply this patch.=C2=A0 Plea= se let me know
> if you agree. And additional testers would be useful.=C2=A0 Anyone?=C2= =A0 Make sure
> to backup your capture templates if something goes wrong.

Some comments follow.

> -@item (file+weektree+prompt "path/to/file")
> -Will create a heading in a week tree, but will prompt for the date. > +one matched.}.=C2=A0 If the optional outline path is given, the tree = will be built
> +under the node it is pointing to. Check out the @code{:time-prompt} a= nd

There's a missing space above.

I wi= ll fix that in the next patch.
=C2=A0

> +(defun org-capture-upgrade-templates (templates)
> +=C2=A0 "Update the template list to the new format.
> +The new format unifies all the date/week tree targets into one that > +also allows for an optional outline path to specify a target." > +=C2=A0 (let (target props)
> +=C2=A0 =C2=A0 (mapcar
> +=C2=A0 =C2=A0 =C2=A0(lambda (ee)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(setq target (car (nth 3 ee)))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(when (memq target '(file+datetree fil= e+datetree+prompt
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0file+= weektree file+weektree+prompt))
> +=C2=A0 =C2=A0 =C2=A0 (setq target (symbol-name target) props nil)
> +=C2=A0 =C2=A0 =C2=A0 (if (string-match "prompt" target) (se= tq props '(:time-prompt t)))
> +=C2=A0 =C2=A0 =C2=A0 (if (string-match "week" target)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq props (append '(:tree-ty= pe week) props)))
> +=C2=A0 =C2=A0 =C2=A0 (setcar (nth 3 ee) 'file+olp+datetree)
> +=C2=A0 =C2=A0 =C2=A0 (setcdr (nthcdr 4 ee) (append props (nthcdr 5 ee= ))))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0ee)
> +=C2=A0 =C2=A0 =C2=A0templates)))

I suggest the following. Less `setq', `setcar', `setcdr' makes = Org
a better place.

(defun org-capture-upgrade-templates (templates)
=C2=A0 "Update the template list to the new format.
TEMPLATES is a template list, as in `org-capture-templates'. The
new format unifies all the date/week tree targets into one that
also allows for an optional outline path to specify a target."
=C2=A0 (mapcar
=C2=A0 =C2=A0(lambda (template)
=C2=A0 =C2=A0 =C2=A0(pcase template
=C2=A0 =C2=A0 =C2=A0 =C2=A0;; Match templates with an obsolete "tree&q= uot; target type. Replace
=C2=A0 =C2=A0 =C2=A0 =C2=A0;; it with common `file+olp-datetree'.=C2=A0= Add new properties
=C2=A0 =C2=A0 =C2=A0 =C2=A0;; (i.e., `:time-prompt' and `:tree-type'= ;) if needed.
=C2=A0 =C2=A0 =C2=A0 =C2=A0(`(,key ,desc ,type (file+datetree . ,path) ,tem= plate . ,props)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 `(,key ,desc ,type (file+olp+datetree ,@path) ,= @props))
=C2=A0 =C2=A0 =C2=A0 =C2=A0(`(,key ,desc ,type (file+datetree+prompt . ,pat= h) ,template . ,props)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 `(,key ,desc ,type (file+olp+datetree ,@path) := time-prompt t ,@props))
=C2=A0 =C2=A0 =C2=A0 =C2=A0(`(,key ,desc ,type (file+weektree . ,path) ,tem= plate . ,props)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 `(,key ,desc ,type (file+olp+datetree ,@path) := tree-type week ,@props))
=C2=A0 =C2=A0 =C2=A0 =C2=A0(`(,key ,desc ,type (file+weektree+prompt . ,pat= h) ,template . ,props)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 `(,key ,desc ,type (file+olp+datetree ,@path) := tree-type week :time-prompt t ,@props))
=C2=A0 =C2=A0 =C2=A0 =C2=A0;; Other templates are left unchanged.
=C2=A0 =C2=A0 =C2=A0 =C2=A0(_ template)))
=C2=A0 =C2=A0templates))

OK, no objecti= ons to a different implementation.=C2=A0 I am not familiar with pcase, look= s general and useful, should learn about it.
=C2=A0

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(file+weektree+prompt= \"path/to/file\")
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Will cr= eate a heading in a week tree, prompts for date
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(file+olp+datetree \&= quot;path/to/file\" \"Level 1 heading\" ...)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Will cr= eate a heading in a date tree for today's date.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0If no h= eadings are given, the tree will be on top level.

Nitpick: It may be just me, but "If no heading is given" sounds b= etter.

OK.
=C2=A0

>=C2=A0 ELisp programs can set KEYS to a string associated with a templa= te
>=C2=A0 in `org-capture-templates'.=C2=A0 In this case, interactive = selection
>=C2=A0 will be bypassed.
> @@ -902,6 +920,7 @@ Store them in the capture property list."
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (insert "* " headline &quo= t;\n")
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (beginning-of-line 0)))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0(`(file+olp ,path . ,outline-path)
> +=C2=A0 =C2=A0 =C2=A0 (setq outline-path (org-capture-sanitize-olp out= line-path))

See below about `org-capture-sanitize-olp'.

Also, it is better to make the `setq' a let-binding when possible.
<= /blockquote>

Hmm, maybe I misunderstand pcase.=C2=A0 I w= as under the impression that when pcase does the match, it will bind the pa= th to outline-path locally (with let or something similar), so that I can, = in the scope of the current match, use setq to change the variable.

Is my understanding incorrect here?

<= blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l= eft:1px solid rgb(204,204,204);padding-left:1ex">
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((m (org-find-olp (cons (org-capture-e= xpand-file path)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0outline-path)= )))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (set-buffer (marker-buffer m))
> @@ -922,59 +941,65 @@ Store them in the capture property list." >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-capture-put :exact-position (po= int))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq target-entry-p
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (and (derived-m= ode-p 'org-mode) (org-at-heading-p)))))

[...]

> +=C2=A0 =C2=A0 =C2=A0(`(file+olp+datetree ,path . ,outline-path)
> +=C2=A0 =C2=A0 =C2=A0 (setq outline-path (org-capture-sanitize-olp out= line-path))

Ditto.

> +=C2=A0 =C2=A0 =C2=A0 (let ((m (if outline-path
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (org-find-olp (cons (org-capture-expand-file path)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0outli= ne-path))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(set-bu= ffer (org-capture-target-buffer path))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(move-m= arker (make-marker) (point)))))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (set-buffer (marker-buffer m))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-capture-put-target-region-and-p= osition)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (widen)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (goto-char m)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (set-marker m nil)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (require 'org-datetree)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-capture-put-target-region-and-p= osition)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (widen)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Make a date/week tree entry, with the = current date (or
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; yesterday, if we are extending dates f= or a couple of hours)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (funcall
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(if (eq (org-capture-get :tree-type= ) 'week)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0#'org-datetree-fi= nd-iso-week-create
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0#'org-datetree-find-date= -create)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(calendar-gregorian-from-absol= ute
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (cond
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(org-overriding-default-time=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Use the overriding defau= lt time.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (time-to-days org-overridin= g-default-time))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((org-capture-get :time-prom= pt)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Prompt for date.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((prompt-time (org-rea= d-date
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 nil t nil "Date for tree en= try:"
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (current-time))))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-capture-put
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0:default-time<= br> > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(cond ((and (o= r (not (boundp 'org-time-was-given))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(not org-time-was-given))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0(not (=3D (time-to-days prompt-time) (org-today= ))))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 ;; Use 00:00 when no time is given for another
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 ;; date than today?
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 (apply #'encode-time
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(append '(0 0 0)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(cl-cdddr (d= ecode-time prompt-time)))))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0((string-match "\\([^ ]+\\)--?[^ ]+[ ]+\\(.*\\)"
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 org-read-date-fina= l-answer)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 ;; Replace any time range by its start.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 (apply #'encode-time
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(org-read-date-analyze
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (replace-match "\\1 \\2" nil = nil
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0org-read-date-final-answer)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 prompt-time (decode-time prompt-time)))= )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0(t prompt-time)))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (time-to-days prompt= -time)))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(t
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Current date, possibly c= orrected for late night
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; workers.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-today))))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;; the following is the keep-restri= ction argument for
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;; org-datetree-find-date-create
=C2=A0 ;; The following...
=C2=A0 ;; ... `org-datetree-find-date-create'.

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(if outline-path 'subtree-at-po= int)

=C2=A0 (and outline-path 'subtree-at-point)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)))

These trailing parens need to be moved above.

OK.
=C2=A0

>=C2=A0 =C2=A0 =C2=A0 =C2=A0(`(file+function ,path ,function)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 (set-buffer (org-capture-target-buffer path= ))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-capture-put-target-region-and-pos= ition)
> @@ -1432,6 +1457,13 @@ Use PREFIX as a prefix for the name of the indi= rect buffer."
>=C2=A0 =C2=A0 (unless (org-kill-is-subtree-p tree)
>=C2=A0 =C2=A0 =C2=A0 (error "Template is not a valid Org entry or = tree")))
>
> +(defun org-capture-sanitize-olp (olp)
> +=C2=A0 "Keep only non-white strings in the list OPL."
> +=C2=A0 (let (res e)
> +=C2=A0 =C2=A0 (while (setq e (pop olp))
> +=C2=A0 =C2=A0 =C2=A0 (and (stringp e) (string-match "\\S-" = e) (push e res)))
> +=C2=A0 =C2=A0 (nreverse res)))

This function is really a one-liner:

=C2=A0 (cl-remove-if-not #'org-string-nw-p olp)

Therefore, I don't think it deserves a dedicated function.

BTW is there any reason to prune non-white strings from the list? Is an
empty string even invalid, since document can contain blank headlines?

The outline path is provided by the user. We can assume he knows what he is doing.

Another option would be to barf if the outline path contains any invalid value instead of silently "fixing" it on user's behalf. E.g.,=

=C2=A0 (when (cl-some #'invalid-value-check olp)
=C2=A0 =C2=A0 (user-error "Invalid outline path in template %S" t= emplate))

for some value of #'invalid-value-check.

WDYT?

Well, I agree with you that we sh= ould not even have this code in here.=C2=A0 It is a hack to solve an issue = I was not able to crack - maybe you can.=C2=A0 Let me explain:
When I use customize to insert a template definition with the = new file+olp+datetree target, I want the outline path to be optional.
=

Here is the relevant part of the customize type definit= ion:

=C2=A0(list :tag "File [ & Outli= ne path ] & Date tree"
(const :format "" file+o= lp+datetree)
,file-variants
(repeat :tag "Outline pa= th" :inline t
(string :tag "Headline")))

The problem is that customize sets this up assuming a= t least one string, in the customize buffer it looks like this
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Target location= : Value Menu File [ & Outline path ] & Date tree:
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Filename =C2=A0 =C2=A0 =C2=A0 : Value Me= nu Literal:=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Outli= ne path:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INS DEL Headli= ne:=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INS
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Template =C2=A0 =C2=A0 =C2=A0 : = Value Menu String:=C2=A0

As you can see, wit= hout the user clicking INS, there is already a string there. So the user wo= uld have to click DEL to make the old empty.=C2=A0 I figured people would f= orget all the time, therefore the hack to remove empty headlines.=C2=A0 It = is critical that the outline path to be empty, because that is used to deci= de if the date trree will be on top level or under a heading.
Do you or anyone know how to tweak customize to start out with = an empty OLP for this application?=C2=A0 The we can remove that part entire= ly.=C2=A0 Otherwise, I am happy to make it a oneliner.
=C2=A0

>=C2=A0 When it is nil, the buffer will be widened to make sure an exist= ing date
> -tree can be found."
> +tree can be found.=C2=A0 If it is the sympol `subtree-at-point', = then the tree
> +will be built under the headline at point."
>=C2=A0 =C2=A0 (setq-local org-datetree-base-level 1)
> -=C2=A0 (or keep-restriction (widen))
>=C2=A0 =C2=A0 (save-restriction
> -=C2=A0 =C2=A0 (let ((prop (org-find-property "DATE_TREE")))=
> -=C2=A0 =C2=A0 =C2=A0 (when prop
> -=C2=A0 =C2=A0 =C2=A0(goto-char prop)
> -=C2=A0 =C2=A0 =C2=A0(setq-local org-datetree-base-level
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(org-ge= t-valid-level (org-current-level) 1))
> -=C2=A0 =C2=A0 =C2=A0(org-narrow-to-subtree)))
> +=C2=A0 =C2=A0 (if (eq keep-restriction 'subtree-at-point)
> +=C2=A0 =C2=A0 =C2=A0(progn
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(or (org-at-heading-p) (error "Not at= heading"))

Nitpick:

=C2=A0 (unless (org-at-heading-p) (error "Not at heading"))

OK
=C2=A0

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(widen)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(org-narrow-to-subtree)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(setq-local org-datetree-base-level
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (org-get-valid-level (org-current-level) 1)))
> +=C2=A0 =C2=A0 =C2=A0 (or keep-restriction (widen))

=C2=A0 (unless keep-restriction (widen))

OK
=C2=A0

> +=C2=A0 =C2=A0 =C2=A0 (let ((prop (org-find-property "DATE_TREE&q= uot;)))
> +=C2=A0 =C2=A0 =C2=A0(when prop
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(goto-char prop)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(setq-local org-datetree-base-level
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (org-get-valid-level (org-current-level) 1))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(org-narrow-to-subtree))))
>=C2=A0 =C2=A0 =C2=A0 (goto-char (point-min))
>=C2=A0 =C2=A0 =C2=A0 (let ((year (calendar-extract-year d))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(month (calendar-extract-month d)) > @@ -84,18 +93,26 @@ tree can be found."
>=C2=A0 =C2=A0 "Find or create an ISO week entry for date D.
>=C2=A0 Compared to `org-datetree-find-date-create' this functi= on creates
>=C2=A0 entries ordered by week instead of months.
> -If KEEP-RESTRICTION is non-nil, do not widen the buffer.=C2=A0 When i= t
> -is nil, the buffer will be widened to make sure an existing date
> -tree can be found."
> +When it is nil, the buffer will be widened to make sure an existing d= ate
> +tree can be found.=C2=A0 If it is the sympol `subtree-at-point', = then the tree
> +will be built under the headline at point."
>=C2=A0 =C2=A0 (setq-local org-datetree-base-level 1)
> -=C2=A0 (or keep-restriction (widen))
>=C2=A0 =C2=A0 (save-restriction
> -=C2=A0 =C2=A0 (let ((prop (org-find-property "WEEK_TREE")))=
> -=C2=A0 =C2=A0 =C2=A0 (when prop
> -=C2=A0 =C2=A0 =C2=A0(goto-char prop)
> -=C2=A0 =C2=A0 =C2=A0(setq-local org-datetree-base-level
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(org-ge= t-valid-level (org-current-level) 1))
> -=C2=A0 =C2=A0 =C2=A0(org-narrow-to-subtree)))
> +=C2=A0 =C2=A0 (if (eq keep-restriction 'subtree-at-point)
> +=C2=A0 =C2=A0 =C2=A0(progn
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(or (org-at-heading-p) (error "Not at= heading"))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(widen)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(org-narrow-to-subtree)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(setq-local org-datetree-base-level
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (org-get-valid-level (org-current-level) 1)))
> +=C2=A0 =C2=A0 =C2=A0 (or keep-restriction (widen))
> +=C2=A0 =C2=A0 =C2=A0 ;; support the old way of tree placement, using = a property
> +=C2=A0 =C2=A0 =C2=A0 (let ((prop (org-find-property "WEEK_TREE&q= uot;)))
> +=C2=A0 =C2=A0 =C2=A0(when prop
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(goto-char prop)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(setq-local org-datetree-base-level
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (org-get-valid-level (org-current-level) 1))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0(org-narrow-to-subtree))))

See above, since the same suggestions apply. Also, it looks like there
is some code duplication involved here. Would it make sense to factor
the common part out of them?

I'll t= ake a look if it does make sense and do it if it is easy.=C2=A0 I see it as= a separate issue since the week tree was implemented using a copy of the d= ate tree function.=C2=A0 But I can merge this change into the patch I am ma= king.
=C2=A0

>=C2=A0 =C2=A0 =C2=A0 (goto-char (point-min))
>=C2=A0 =C2=A0 =C2=A0 (require 'cal-iso)
>=C2=A0 =C2=A0 =C2=A0 (let* ((year (calendar-extract-year d))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0Modified lisp/org.el
> diff --git a/lisp/org.el b/lisp/org.el
> index 38fce70..ac56d71 100644
> --- a/lisp/org.el
> +++ b/lisp/org.el
> @@ -16615,6 +16615,8 @@ only headings."
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 end found flevel)
>=C2=A0 =C2=A0 =C2=A0 (unless buffer (error "File not found :%s&quo= t; file))
>=C2=A0 =C2=A0 =C2=A0 (with-current-buffer buffer
> +=C2=A0 =C2=A0 =C2=A0 (unless (derived-mode-p 'org-mode)
> +=C2=A0 =C2=A0 =C2=A0(error "Buffer %s needs to be in org-mode&qu= ot; buffer))

Nitpick: "Buffer %s needs to be in Org mode"

OK
=C2=A0

Ideally, a bunch of tests in test-org-capture.el would be nice.

Will do so after we have converged.

=
Regards

Carsten
=C2=A0
<= blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l= eft:1px solid rgb(204,204,204);padding-left:1ex">

Regards,

--
Nicolas Goaziou

--001a113f9fe23bdb510547c626f1--