colonelpanic8 / org-project-capture

Manage org-mode TODOs for your projectile projects

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

capture into sub heading

xiaoxinghu opened this issue · comments

I am using one file strategy, with projects being level 1 headings. Is it possible to capture entries into sub headings? E.g. I want to capture notes into level 2 heading ** Inbox under each projects.

This is the same as #28 right?

I've done all the legwork to support this in org-category-capture, and if you defined your own org-projectile-strategy you could probably get this to work pretty easily.

With that said, it should be relatively easy to add support to this for org-projectile now. Since this has been requested a few times, I'll probably make some quick changes to support it.

Not exactly the same. What #28 wanted was, if I understand it correctly:

; work.org
* Projects
** Project 1
*** TODO captured notes here

** Project 2

My scenario:

; projects.org
* Project 1
** Inbox
*** captured notes for project 1
...
* Project 2
** Inbox
*** captured notes for project 2

My motivation was that I have a template structure for each of my projects:

* My Awesome Project
** Inbox
** Ideas
** New Features
** Bugs
...

I'd like to capture new notes/todos under Inbox, so that it doesn't clutter the structure.
Don't know if that's a sensible requirement or it's my own odd use case.

Oh I see. Yeah I guess I just skimmed the original issue text and assumed you were asking for the same thing.

What you are asking for is not currently possible, although it wouldn't be too hard to get things to work that way with a bit of custom code.

subclass org-projectile-single-file-strategy and override as follows:

(defclass org-projectile-single-file-inbox
  (org-projectile-single-file-strategy) nil)

(defmethod occ-get-capture-marker
    ((strategy org-projectile-single-file-strategy) context)
  (with-slots (category) context
    (let ((filepath (occ-get-capture-file strategy category)))
      (with-current-buffer (find-file-noselect filepath)
        (save-excursion
          (occ-goto-or-insert-category-heading
           category
           :build-heading 'org-projectile-build-heading
           :get-category-from-element 'org-projectile-get-category-from-heading)
          (code-to-navigate-wherever-you-want-within-the-heading)
          (point-marker))))))

(setq org-projectile-strategy (make-instance 'org-projectile-single-file-inbox))

Obviously you'll need to replace code-to-navigate-wherever-you-want-within-the-heading with something that does what you want. Should be pretty simple though.

@xiaoxinghu Were you able to try the snippet that I posted? I think it should do what you want.

commented

I just wanted to reflect on the previous request. I was wondering if it is possible to define org-capture template that will behave similarly to the org-projectile-project-todo-completing-read. My goal is: before the capture chooses a project and then add customized TODO headline under already defined parent headline. I am using per-project files, and wish to capture meeting notes that will always be stored under a * Meetings headline in a project-specific org file. Thanks!

I just wanted to reflect on the previous request. I was wondering if it is possible to define org-capture template that will behave similarly to the org-projectile-project-todo-completing-read. My goal is: before the capture chooses a project and then add customized TODO headline under already defined parent headline. I am using per-project files, and wish to capture meeting notes that will always be stored under a * Meetings headline in a project-specific org file. Thanks!

@przemo
I'm not sure I understand your request. If you want org-projectile to provide a capture template, it already does that. To put it under the meetings heading, you just need to write the code to direct it there, which should be easy.

commented

Yeah, I am very bad LISP programmer.

@przemo Should be like one line. Something like (org-goto-heading "Meetings") (I can't remember the exaxct incantation)

I tried it out @IvanMalison with the hope to achieve something else. I wanted org-projectile to create a subheading with the base-name of the file I was capturing from and then insert the todo in there.

So I tried the following:

(use-package org-projectile
  :bind (("C-c n p" . org-projectile-project-todo-completing-read)
         ("C-c c" . org-capture))
  :config
  (progn
    (org-projectile-per-project)
    (setq org-projectile-per-project-filepath "README.org")
    (setq org-agenda-files (append org-agenda-files (org-projectile-todo-files))))
  :ensure t)

(defclass org-projectile-single-file-inbox
  (org-projectile-single-file-strategy) nil)

(defmethod occ-get-capture-marker
  ((strategy org-projectile-single-file-strategy) context)
  (with-slots (category) context
    (let ((filepath (occ-get-capture-file strategy category)))
      (with-current-buffer (find-file-noselect filepath)
        (save-excursion
          (occ-goto-or-insert-category-heading
           category
           :build-heading 'org-projectile-build-heading
           :get-category-from-element 'org-projectile-get-category-from-heading)
          (org-goto file-name-base)
          (point-marker))))))

(setq org-projectile-strategy (make-instance 'org-projectile-single-file-inbox)

But it did not work. Any idea what I am doing wrong?

@Cumol what is file-name-base I don't see where that is defined. This should just error right?

You're also missing a paren on the last line.

@Cumol Also, I don't think the code you wrote there would ever create a new heading, it would only go to an existing heading.

Something like this shoudl work:

(defclass org-projectile-single-file-with-filenames
  (org-projectile-single-file-strategy) nil)

(defun occ-goto-or-insert-subheading (subheading)
  (let ((heading-location (occ-get-category-heading-location subheading
                                                            :goto-subheading t)))
  (if heading-location
      (goto-char heading-location)
    (org-insert-subheading)
    (insert subheading))))

(defmethod occ-get-capture-marker
    ((strategy org-projectile-single-file-strategy) context)
  (with-slots (category) context
    (let ((filepath (occ-get-capture-file strategy category)))
      (with-current-buffer (find-file-noselect filepath)
        (save-excursion
          (occ-goto-or-insert-category-heading
           category
           :build-heading 'org-projectile-build-heading
           :get-category-from-element 'org-projectile-get-category-from-heading)
          (occ-goto-or-insert-subheading (org-capture-get :original-file))
          (point-marker))))))

(setq org-projectile-strategy (make-instance 'org-projectile-single-file-with-filenames))

When starting emacs I get the following message:

eieio-defclass-internal: Given parent class org-projectile-single-file-strategy is not a class
Given parent class org-projectile-single-file-strategy is not a class

When trying out org-projectile-capture-for-current-project I get the indirect buffer to enter my entry but it is just appended to the end of the file and not as intended.

I have very little experience with emacs lisp so I am sorry if this feels one-sided.

My following setup of org-projectile is the following:

(use-package org-projectile
  :bind (("C-c n p" . org-projectile-project-todo-completing-read)
         ("C-c c" . org-capture))
  :config
  (progn
    (org-projectile-per-project)
    (setq org-projectile-per-project-filepath "README.org")
    (setq org-agenda-files (append org-agenda-files (org-projectile-todo-files))))
  :ensure t)

(defclass org-projectile-single-file-with-filenames
  (org-projectile-single-file-strategy) nil)

(defun occ-goto-or-insert-subheading (subheading)
  (let ((heading-location (occ-get-category-heading-location subheading
                                                            :goto-subheading t)))
  (if heading-location
      (goto-char heading-location)
    (org-insert-subheading)
    (insert subheading))))

(defmethod occ-get-capture-marker
  ((strategy org-projectile-single-file-strategy) context)
  (with-slots (category) context
    (let ((filepath (occ-get-capture-file strategy category)))
      (with-current-buffer (find-file-noselect filepath)
        (save-excursion
          (occ-goto-or-insert-category-heading
           category
           :build-heading 'org-projectile-build-heading
           :get-category-from-element 'org-projectile-get-category-from-heading)
          (occ-goto-or-insert-subheading (org-capture-get :original-file))
          (point-marker))))))

(setq org-projectile-strategy (make-instance 'org-projectile-single-file-with-filenames))

eieio-defclass-internal: Given parent class org-projectile-single-file-strategy is not a class
Given parent class org-projectile-single-file-strategy is not a class

That is likely because you havent required org-projectile before this definition.

i.e. all of that stuff needs to appear inside the config of your org-projectile package

Moved everything into the (progn) call and restarted emacs
Tried org-projectile-capture-for-current-project as before and got the following error:

occ-get-category-heading-location: Symbol’s function definition is void: t

@xiaoxinghu I'm going to argue that #36 (comment)

shows how to do this.