emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* org-refile-target-verify-function - use inherited tag & todo
@ 2019-10-27 20:03 Nathan Neff
  2019-10-27 22:58 ` Gustavo Barros
  0 siblings, 1 reply; 5+ messages in thread
From: Nathan Neff @ 2019-10-27 20:03 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1380 bytes --]

Hi all, I want to filter my refile targets to "Tasks" headings.  This
snippet works:
https://lists.gnu.org/r/emacs-orgmode/2016-02/msg00088.html

There's a few things I'd like to improve on:

1) My org-agenda-files show up in the list.  For example, foo.org and
bar.org show up in the refile targets, despite the function should return
nil if a heading does not contain "Tasks"

2) I would like to limit the "Task" headings to those that have a parent
heading with a tag :project:
I have :project: tag as exclude-from-inheritance, so this might be tricky

3) I would like the parent heading with :project: tag to have a TODO state
that is not "done" and is not "cancelled".

Can anyone help me improve on this?  I think I'm missing some really easy
documentation / examples.  As an aside, is there a definitive "Org Mode
API" doc that shows the functions that would assist me in writing a
function to perform the above filtering?  Something like a Javadoc for
Org-Mode?  There's great articles, etc. but I think it would be cool to
have a "public" API defined / documented - otherwise it seems that I'm
simply going through existing blogs, documentation etc and of course the
source code.  When going through source code, there's many functions that
are named similarly and yes there's docs but I found myself wanting some
kind of Javadoc-ish API documentation :)

Thanks,
--Nate

[-- Attachment #2: Type: text/html, Size: 1858 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: org-refile-target-verify-function - use inherited tag & todo
  2019-10-27 20:03 org-refile-target-verify-function - use inherited tag & todo Nathan Neff
@ 2019-10-27 22:58 ` Gustavo Barros
  2019-11-02  0:47   ` Nathan Neff
  0 siblings, 1 reply; 5+ messages in thread
From: Gustavo Barros @ 2019-10-27 22:58 UTC (permalink / raw)
  To: Nathan Neff; +Cc: emacs-orgmode

Hi Nate,

On Sun, Oct 27 2019, Nathan Neff wrote:

> 1) My org-agenda-files show up in the list.  For example, foo.org and bar.org show up in the refile targets, despite the
> function should return nil if a heading does not contain "Tasks"

Curiously, I’ve been scratching this itch just today. So I might as well
share.

I presume you are using some of the specific values of
`org-refile-use-outline-path'. If that’s the case, the file level as a
refile target is hardcoded in `org-refile-get-targets', independently of
what you might have in `org-refile-target-verify-function'.

We have somewhere in `org-refile-get-targets':

#+begin_src emacs-lisp
(when (eq org-refile-use-outline-path 'file)
  (push (list (file-name-nondirectory f) f nil nil) tgs))
(when (eq org-refile-use-outline-path 'buffer-name)
  (push (list (buffer-name (buffer-base-buffer)) f nil nil) tgs))
(when (eq org-refile-use-outline-path 'full-file-path)
  (push (list (file-truename (buffer-file-name (buffer-base-buffer))) f nil nil) tgs))
#+end_src

(`tgs' is the local variable which is collecting candidates for return).

So, you might not use `org-refile-use-outline-path'. In this case the
file info will be provided in the end of the refile target in
parentheses (for targets outside the current buffer). And the file level
will not be offered as a target.

I, however like `org-refile-use-outline-path' and set it to 'file. But I
also want to not be able to refile to the file level. So I advised
`org-refile-get-targets' with:

#+begin_src emacs-lisp
(defun my/org-refile-filter-targets (orig-fun &rest args)
  (let ((targets (apply orig-fun args))
        (agenda-files (mapcar #'file-name-nondirectory org-agenda-files)))
    (cl-remove-if (lambda (x)
                    (member (car x) agenda-files))
                  targets)))
(advice-add 'org-refile-get-targets :around #'my/org-refile-filter-targets)
#+end_src

This presumes (setq org-refile-use-outline-path 'file). If you use any
other value, you should probably adjust the function’s let bound
variables for the case. This is also sort of hackish, so exert your own
due caution in choosing whether or not to use it.

HTH,
Gustavo.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: org-refile-target-verify-function - use inherited tag & todo
  2019-10-27 22:58 ` Gustavo Barros
@ 2019-11-02  0:47   ` Nathan Neff
  2019-11-02 13:06     ` Gustavo Barros
  0 siblings, 1 reply; 5+ messages in thread
From: Nathan Neff @ 2019-11-02  0:47 UTC (permalink / raw)
  To: Gustavo Barros; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 3406 bytes --]

Thanks Gustavo, notes below:

On Sun, Oct 27, 2019 at 5:58 PM Gustavo Barros <gusbrs.2016@gmail.com>
wrote:

> Hi Nate,
>
> On Sun, Oct 27 2019, Nathan Neff wrote:
>
> > 1) My org-agenda-files show up in the list.  For example, foo.org and
> bar.org show up in the refile targets, despite the
> > function should return nil if a heading does not contain "Tasks"
>
> Curiously, I’ve been scratching this itch just today. So I might as well
> share.
>
> I presume you are using some of the specific values of
> `org-refile-use-outline-path'. If that’s the case, the file level as a
> refile target is hardcoded in `org-refile-get-targets', independently of
> what you might have in `org-refile-target-verify-function'.
>
> We have somewhere in `org-refile-get-targets':
>
> #+begin_src emacs-lisp
> (when (eq org-refile-use-outline-path 'file)
>   (push (list (file-name-nondirectory f) f nil nil) tgs))
> (when (eq org-refile-use-outline-path 'buffer-name)
>   (push (list (buffer-name (buffer-base-buffer)) f nil nil) tgs))
> (when (eq org-refile-use-outline-path 'full-file-path)
>   (push (list (file-truename (buffer-file-name (buffer-base-buffer))) f
> nil nil) tgs))
> #+end_src
>
> (`tgs' is the local variable which is collecting candidates for return).
>
> So, you might not use `org-refile-use-outline-path'. In this case the
> file info will be provided in the end of the refile target in
> parentheses (for targets outside the current buffer). And the file level
> will not be offered as a target.
>
> I, however like `org-refile-use-outline-path' and set it to 'file. But I
> also want to not be able to refile to the file level. So I advised
> `org-refile-get-targets' with:
>
> #+begin_src emacs-lisp
> (defun my/org-refile-filter-targets (orig-fun &rest args)
>   (let ((targets (apply orig-fun args))
>         (agenda-files (mapcar #'file-name-nondirectory org-agenda-files)))
>     (cl-remove-if (lambda (x)
>                     (member (car x) agenda-files))
>                   targets)))
> (advice-add 'org-refile-get-targets :around #'my/org-refile-filter-targets)
> #+end_src
>

> This presumes (setq org-refile-use-outline-path 'file). If you use any
> other value, you should probably adjust the function’s let bound
> variables for the case. This is also sort of hackish, so exert your own
> due caution in choosing whether or not to use it.
>

Indeed, I do use org-refile-use-outline-path 'file.  However, I have a
simple
directory specified for my org-agenda-files.  ("~/org-mode")  Therefore
I'll need to
do something a bit different.

It appears that your solution creates "targets" which is the targets list
of course, and
then it creates "agenda-files" which goes through org-agenda-files and
finds all the filenames
in org-agenda files.

It then mutates "targets", and removes any entry which is a filename from
org-agenda-files.

Since my org-agenda-files is simply ("~/org-mode/") none of the entries
match.

Hmmm, let me ask:  Why not simply go through targets and remove any entry
whose value is
a simple filename?  Why search org-agenda-files first?  This function also
assumes that the org-refile-targets
always comes from org-agenda-files.

I'll play with your function and see what I can get -- thank you for the
head-start!

Thanks
--Nate

>
> HTH,
> Gustavo.
>

[-- Attachment #2: Type: text/html, Size: 4720 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: org-refile-target-verify-function - use inherited tag & todo
  2019-11-02  0:47   ` Nathan Neff
@ 2019-11-02 13:06     ` Gustavo Barros
  2021-02-28 23:00       ` Nathan Neff
  0 siblings, 1 reply; 5+ messages in thread
From: Gustavo Barros @ 2019-11-02 13:06 UTC (permalink / raw)
  To: Nathan Neff; +Cc: emacs-orgmode

Hi Nate,

On Fri, Nov 01 2019, Nathan Neff wrote:

> Indeed, I do use org-refile-use-outline-path 'file.  However, I have a
> simple
> directory specified for my org-agenda-files.  ("~/org-mode") 
> Therefore
> I'll need to
> do something a bit different.
>
> It appears that your solution creates "targets" which is the targets 
> list
> of course, and
> then it creates "agenda-files" which goes through org-agenda-files and
> finds all the filenames
> in org-agenda files.
>
> It then mutates "targets", and removes any entry which is a filename 
> from
> org-agenda-files.
>
> Since my org-agenda-files is simply ("~/org-mode/") none of the 
> entries
> match.
>
> Hmmm, let me ask:  Why not simply go through targets and remove any 
> entry
> whose value is
> a simple filename?  Why search org-agenda-files first?  This function 
> also
> assumes that the org-refile-targets
> always comes from org-agenda-files.
>
> I'll play with your function and see what I can get -- thank you for 
> the
> head-start!
>
> Thanks
> --Nate

I'm glad this might be useful to you.  And you are correct in all of 
observations.

My main point is simply that, as things stand, you won't be able to trim 
the file level candidates with `org-refile-target-verify-function`, as 
they are hardcoded.  But this simple function is the sketch of a 
(hackish) way.

`org-refile-get-targets`' main purpose is to return the list of 
targets. The advice function grabs this return value, filters the list 
and returns the filtered list.  How it filters may depend, as you noted. 
I've chosen a simple criterion which meets my use case 
(`org-agenda-files`, as I specify the individual files directly there, 
and use only those as refile targets).  Indeed, it does make some 
presumptions, as you noted.  (The function does not "search 
org-agenda-files" though, it just gets the list of their names, which is 
contained in the variable).  In your case, you will certainly have to 
devise another filtering criterion.  I think the one you suggest is a 
good one too.

Best regards,
Gustavo.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: org-refile-target-verify-function - use inherited tag & todo
  2019-11-02 13:06     ` Gustavo Barros
@ 2021-02-28 23:00       ` Nathan Neff
  0 siblings, 0 replies; 5+ messages in thread
From: Nathan Neff @ 2021-02-28 23:00 UTC (permalink / raw)
  To: Gustavo Barros; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 2937 bytes --]

Thank you Gustavo, I got this to work after revisiting!

I changed my org-agenda-files to a single variable "org-agenda-files.org" ,
and populated
the file with my agenda files.

I modified the wrapper script to call the (org-agenda-files) function.

This is so nice - I have a lot of org-mode files and the ability to remove
files "root" heading is really nice when filtering by tag.

#+begin_src emacs-lisp
(defun njn-org-refile-filter-targets (orig-fun &rest args)
  (let ((targets (apply orig-fun args))
        (agenda-files (mapcar #'file-name-nondirectory (org-agenda-files))))
    (cl-remove-if (lambda (x)
                    (member (car x) agenda-files)) targets)))

#+end_src


On Sat, Nov 2, 2019 at 8:06 AM Gustavo Barros <gusbrs.2016@gmail.com> wrote:

> Hi Nate,
>
> On Fri, Nov 01 2019, Nathan Neff wrote:
>
> > Indeed, I do use org-refile-use-outline-path 'file.  However, I have a
> > simple
> > directory specified for my org-agenda-files.  ("~/org-mode")
> > Therefore
> > I'll need to
> > do something a bit different.
> >
> > It appears that your solution creates "targets" which is the targets
> > list
> > of course, and
> > then it creates "agenda-files" which goes through org-agenda-files and
> > finds all the filenames
> > in org-agenda files.
> >
> > It then mutates "targets", and removes any entry which is a filename
> > from
> > org-agenda-files.
> >
> > Since my org-agenda-files is simply ("~/org-mode/") none of the
> > entries
> > match.
> >
> > Hmmm, let me ask:  Why not simply go through targets and remove any
> > entry
> > whose value is
> > a simple filename?  Why search org-agenda-files first?  This function
> > also
> > assumes that the org-refile-targets
> > always comes from org-agenda-files.
> >
> > I'll play with your function and see what I can get -- thank you for
> > the
> > head-start!
> >
> > Thanks
> > --Nate
>
> I'm glad this might be useful to you.  And you are correct in all of
> observations.
>
> My main point is simply that, as things stand, you won't be able to trim
> the file level candidates with `org-refile-target-verify-function`, as
> they are hardcoded.  But this simple function is the sketch of a
> (hackish) way.
>
> `org-refile-get-targets`' main purpose is to return the list of
> targets. The advice function grabs this return value, filters the list
> and returns the filtered list.  How it filters may depend, as you noted.
> I've chosen a simple criterion which meets my use case
> (`org-agenda-files`, as I specify the individual files directly there,
> and use only those as refile targets).  Indeed, it does make some
> presumptions, as you noted.  (The function does not "search
> org-agenda-files" though, it just gets the list of their names, which is
> contained in the variable).  In your case, you will certainly have to
> devise another filtering criterion.  I think the one you suggest is a
> good one too.
>
> Best regards,
> Gustavo.
>

[-- Attachment #2: Type: text/html, Size: 4010 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-02-28 23:01 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-27 20:03 org-refile-target-verify-function - use inherited tag & todo Nathan Neff
2019-10-27 22:58 ` Gustavo Barros
2019-11-02  0:47   ` Nathan Neff
2019-11-02 13:06     ` Gustavo Barros
2021-02-28 23:00       ` Nathan Neff

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

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).