5

I have a function called create-org-link that creates a file link based on an arbitrary string that I pass to it. I would like to be able to invoke this function when I invoke org capture.

Here's what I have tried:

(setq org-capture-templates
  '(("w" "Work Log" entry (file+headline "c:/td/gtd/org/WorkLogs.org" "Today") "** %(create-org-link) %?")
))

I know that the function works because I can use it outside of this template. However, when I execute if from here I get the following output:

** %![Error: (wrong-number-of-arguments (lambda (title) Foobar de roobarb (interactive sPlease enter a title: ) (insert (format [[file:%s-%s.org][%s - %s]] (format-time-string org-link-date-stamp-format (current-time)) (replace-regexp-in-string    title) (format-time-string org-link-date-stamp-format (current-time)) title))) 0)] 

Is there a different template element that I should be using?

Edit - 5/5/2014 @ 12:48

Here's the function that is being called:

(defun create-org-link (title)
  "Foobar de roobarb"
  (interactive "sPlease enter a title: ")
  (insert (format "[[file:%s-%s.org][%s - %s]]" (format-time-string org-link-date-stamp-format(current-time)) (replace-regexp-in-string " " "" title) (format-time-string org-link-date-stamp-format(current-time)) title)))

(defvar org-link-date-stamp-format "%y%m%d"
  "Format of date stamps to use in Org links")

Ha ha - I guess I should take out my placeholder comments before asking questions about it in a forum :-)

4
  • Have you tried (call-interactively #'create-org-link)?
    – Dan
    May 4, 2015 at 14:48
  • Thanks Dan! I get this: byte-code: Capture abort: (wrong-type-argument char-or-string-p nil)
    – Tom Purl
    May 4, 2015 at 18:54
  • You don't show all of the code you are using. But clearly the lambda form you show (from the error msg) is not a function. You have 3 (unquoted) symbols after the argument list and before the interactive spec: Foobar de roobarb. See the definitions of a function, command, and lambda form. Probably you meant to put double quotes around Foobar de roobarb, to create a doc string.
    – Drew
    May 4, 2015 at 22:40
  • 2
    This is probably best done by defining a function for the template where you can prompt for your link argument. Cf. emacs.stackexchange.com/q/10294/2710 May 5, 2015 at 8:07

1 Answer 1

4

You can use the following:

(defun create-org-link (&optional title)
  "Foobar de roobarb"
  (interactive)
  (unless title
    (setq title
          (read-string "Please enter a title: ")))
  (let ((out (format "[[file:%s-%s.org][%s - %s]]"
                     (format-time-string
                      org-link-date-stamp-format(current-time))
                     (replace-regexp-in-string " " "" title)
                     (format-time-string
                      org-link-date-stamp-format(current-time))
                     title)))
    (if (called-interactively-p)
        (insert out)
      out)))

Rather than prompt for the title as part of the interactive call, prompt for it manually if it wasn't passed. org-capture doesn't default to interactive when calling the function.

Wrapping it as (call-interactively #'create-org-link) would work as well, however you will need to remove insert so that only the format call is passed. Otherwise the data is inserted into the wrong buffer (as part of the prompt/parsing rather than passed to the final template).

The if statement at the end of the function takes care of inserting it (when interactive) vs returning the string (when called from the template).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.